【问题标题】:Check if a directory is readable检查目录是否可读
【发布时间】:2011-04-25 19:50:55
【问题描述】:

我们如何检查一个目录是否是只读的?

【问题讨论】:

  • @Oded:虽然这个问题确实很简洁,但它确实包含了回答它所需的所有信息,因为它被标记为 Delphi...

标签: delphi


【解决方案1】:

您可以使用FileGetAttr 函数并检查是否设置了faReadOnly 标志。

试试这个代码

function DirIsReadOnly(Path:string):Boolean;
var
 attrs    : Integer;
begin
 attrs  := FileGetAttr(Path);
 Result := (attrs  and faReadOnly) > 0;
end;

【讨论】:

  • 想法:如果 Path 指向“目录以外的东西”,代码可以(作为“特殊奖励”)抛出异常 - 或使用 Assert(DirectoryExists(Path))?
  • 此代码不适用于 Windows 上的文件夹,仅适用于文件。 Windows 文件和文件夹属性基于旧 FAT,不包括文件夹的 Read-only 属性。这些在迁移到 NTFS 时从未更新,但 NTFS 的高级ACLAccess Control List 功能可用于将文件夹设置为只读。我下面的答案(改编自HeartWaves)更可靠。有关更多详细信息,请参阅本文:support.microsoft.com/en-gb/help/326549/…
【解决方案2】:

在 Windows API 方式中,它是:

fa := GetFileAttributes(PChar(FileName))
if (fa and FILE_ATTRIBUTE_DIRECTORY <> 0) and (fa and FILE_ATTRIBUTE_READONLY <> 0) then
  ShowMessage('Directory is read-only');

【讨论】:

  • 这个答案对文件是正确的,但对文件夹不正确。 Windows(所有版本)不为文件夹设置 FILE_ATTRIBUTE_READONLY。请参阅提供更多详细信息的此问题:superuser.com/questions/1247843/…
【解决方案3】:

测试目录的属性是否为 R/O 只是答案的一部分。您可以轻松地拥有一个仍然无法写入的 R/W 目录 - 因为访问权限。

检查是否可以写入目录的最佳方法是 - 尝试一下:

FUNCTION WritableDir(CONST Dir : STRING) : BOOLEAN;
  VAR
    FIL : FILE;
    N   : STRING;
    I   : Cardinal;

  BEGIN
    REPEAT
      N:=IncludeTrailingPathDelimiter(Dir);
      FOR I:=1 TO 250-LENGTH(N) DO N:=N+CHAR(RANDOM(26)+65)
    UNTIL NOT FileExists(N);
    Result:=TRUE;
    TRY
      AssignFile(FIL,N);
      REWRITE(FIL,1);
      Result:=FileExists(N); // Not sure if this is needed, but AlainD says so :-)
    EXCEPT
      Result:=FALSE
    END;
    IF Result THEN BEGIN
      CloseFile(FIL); 
      ERASE(FIL)
    END
  END;

【讨论】:

  • 第一眼看起来像 COBOL 或 FORTRAN :)
  • 你所做的接近于最糟糕的方式。不必要的文件系统,高清负担。接下来,如果您附加了某种 fs 更改订阅者怎么办?最好的方法就是写下你计划在那里写的任何东西。如果目录受到保护,您将收到错误消息。就是这样。
  • 同意。但是,如果由于某种原因您需要事先知道该目录是否可写,那么唯一的方法就是——正如你自己所暗示的——就这样做。上面的函数就是这样做并返回结果。
  • @HeartWare:酷,已经删除了我之前的评论。需要额外检查,因为Active Control List (ACL) 可以拒绝当前用户的写入权限。当我测试代码时,文件没有被写入......但没有抛出异常。腰带和大括号:o)
【解决方案4】:

HeartWare 给出的版本很好,但包含两个错误。这个修改后的版本工作更可靠,并且有 cmets 来解释发生了什么:

function IsPathWriteable(const cszPath: String) : Boolean;
var
    fileTest: file;
    szFile: String;
    nChar: Cardinal;
begin
    // Generate a random filename that does NOT exist in the directory
    Result := True;
    repeat
        szFile := IncludeTrailingPathDelimiter(cszPath);
        for nChar:=1 to (250 - Length(szFile)) do
            szFile := (szFile + char(Random(26) + 65));
    until (not FileExists(szFile));

    // Attempt to write the file to the directory. This will fail on something like a CD drive or
    // if the user does not have permission, but otherwise should work.
    try
        AssignFile(fileTest, szFile);
        Rewrite(fileTest, 1);

        // Note: Actually check for the existence of the file. Windows may appear to have created
        // the file, but this fails (without an exception) if advanced security attibutes for the
        // folder have denied "Create Files / Write Data" access to the logged in user.
        if (not FileExists(szFile)) then
            Result := False;
    except
        Result := False;
    end;

    // If the file was written to the path, delete it
    if (Result) then
        begin
        CloseFile(fileTest);
        Erase(fileTest);
        end;
end;

【讨论】:

  • 这太复杂了。见:stackoverflow.com/a/46094359/937125
  • 当我回答这个问题时,我不知道另一个问题。但是,不同意这是way too complex。它做同样的事情:尝试写一个文件。如果成功,则该目录不是只读的。
【解决方案5】:

一种可能的方法是尝试列出该目录中的文件并检查状态。这样我们就可以检查它是否可读。此答案适用于 2009 年或更低版本。请记住,我们必须检查文件夹是否存在,然后检查该文件夹是否可读。你可以在这里找到实现http://simplebasics.net/delphi-how-to-check-if-you-have-read-permission-on-a-directory/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 2015-11-11
    • 2010-12-08
    • 1970-01-01
    • 2014-08-04
    • 2015-01-09
    相关资源
    最近更新 更多