代码之家  ›  专栏  ›  技术社区  ›  mjn anonym

如何使用Delphi测试目录是否可写?

  •  9
  • mjn anonym  · 技术社区  · 14 年前

    目前我使用这个函数,基于JCL代码,它可以很好地工作:

    function IsDirectoryWriteable(const AName: string): Boolean;
    var
      FileName: PWideChar;
      H: THandle;
    begin
      FileName := PWideChar(IncludeTrailingPathDelimiter(AName) + 'chk.tmp');
    
      H := CreateFile(FileName, GENERIC_READ or GENERIC_WRITE, 0, nil,
        CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0);
    
      Result := H <> INVALID_HANDLE_VALUE;
    
      DeleteFile(FileName);
    end;
    

    旗子有什么我可以改进的吗? 可以在不实际创建文件的情况下完成测试吗? 或者这个功能在RTL或绝地图书馆中已经可用了吗?

    4 回复  |  直到 7 年前
        1
  •  18
  •   Remy Lebeau    14 年前

    实际上,写入目录是确定目录是否可写的最简单的方法。有太多的安全选项可供单独检查,即使这样,您可能会错过一些东西。

    在调用deletefile()之前,还需要关闭打开的句柄。因为您使用的是 FILE_FLAG_DELETE_ON_CLOSE 旗帜。

    顺便说一句,您的代码中有一个小错误。您正在创建一个临时字符串并将其分配给pwidechar,但在实际使用pwidechar之前,该字符串超出了作用域,释放了内存。文件名变量应该是字符串而不是pWideChar。调用createfile()时执行类型转换,而不是之前。

    试试这个:

    function IsDirectoryWriteable(const AName: string): Boolean; 
    var 
      FileName: String; 
      H: THandle; 
    begin 
      FileName := IncludeTrailingPathDelimiter(AName) + 'chk.tmp'; 
      H := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, 
        CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0); 
      Result := H <> INVALID_HANDLE_VALUE; 
      if Result then CloseHandle(H);
    end; 
    
        2
  •  3
  •   kobik    7 年前

    这是我的版本使用 GetTempFileName 它将尝试创建一个 独特的 目标目录中的临时文件:

    function IsDirecoryWriteable(const AName: string): Boolean;
    var
      TempFileName: array[0..MAX_PATH] of Char;
    begin
      { attempt to create a temp file in the directory }
      Result := GetTempFileName(PChar(AName), '$', 0, TempFileName) <> 0;
      if Result then
        { clean up }
        Result := DeleteFile(TempFileName);
    end;
    
        3
  •  2
  •   Erik Knowles    14 年前

    安德烈亚斯…

    使用安全API获取文件/目录的有效权限是一个PIA混乱,只是不可靠。(为了检查是否可以在dir中写入文件,我放弃了所有这样做的代码。)

    C.F. http://www.ureader.com/msg/16591730.aspx

    (我有其他参考资料,但我是新用户,只能发布一个链接。只需按照上面链接中给出的URL进行操作。)

        4
  •  0
  •   Norman Rorke    7 年前

    当然,您需要做的只是验证您对目录的访问权限。这有什么问题:

    function IsDirectoryWriteable(aName : String);
    var
      FileObject : TJwSecureFileObject;
      DesiredAccess: ACCESS_MASK;
    begin
      DesiredAccess := FILE_GENERIC_WRITE;
      FileObject := TJwSecureFileObject.Create(aName);
      try
        result := FileObject.AccessCheck(DesiredAccess);
      finally
        FileObject.Free;
      end;
    end;