2010-10-15 141 views
7

如何检查目录是否只读?检查目录是否可读

+4

@Oded:虽然问题确实简洁,确实能包含所有回答这个问题,因为它的标签德尔福所需的信息。 .. – 2010-10-15 09:45:06

回答

4

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

试试这个代码

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

想法:如果Path指向“除目录之外的其他东西”,或者使用Assert(DirectoryExists(Path)),则代码可能(作为“特殊奖励”)抛出异常? – mjn 2010-10-15 14:36:26

+1

此代码不适用于Windows上的文件夹,仅适用于文件。 Windows文件和文件夹属性基于传统FAT,它不包含文件夹的“只读”属性。这些在迁移到NTFS时从未更新过,但是可以使用NTFS的高级'ACL'或'访问控制列表'功能使文件夹为只读。我的回答如下(改编自'HeartWave's)更可靠。有关更多详细信息,请参阅此文章:https://support.microsoft.com/en-gb/help/326549/you-cannot-view-or-change-the-read-only-or-the-system-attributes-of -fo – AlainD 2017-09-07 09:15:10

0

在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'); 
+0

此答案对文件正确,但不适用于文件夹。 Windows(所有版本)不为文件夹设置FILE_ATTRIBUTE_READONLY。看到这个问题给出了更多的细节:https://superuser.com/questions/1247843/why-can-i-write-files-into-a-folder-that-is-read-only/1247851?noredirect=1#评论1831434_1247851 – AlainD 2017-09-06 11:26:58

2

测试,如果该目录的属性是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; 
+1

看起来像COBOL或FORTRAN在我看来:) – mjn 2010-10-15 14:25:45

+0

和COBOL时代的代码一样粗暴,heh – 2010-10-19 02:39:02

+0

你所做的是接近最糟糕的方式。不必要的文件系统,高清负担。接下来,如果你有某种类型的fs改变订阅者,该怎么办?最好的办法就是写下你计划写在那里的任何东西。如果该目录受到保护,则会出现错误。而已。 – himself 2010-10-19 12:34:18

1

版本HeartWare给是好的,但包含了两个错误。这个修改后的版本工作更可靠,并具有注释来解释正在发生的事情:

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; 
+1

这太复杂了。请参阅:https://stackoverflow.com/a/46094359/937125 – kobik 2017-09-07 10:49:13

+0

当我回答这个问题时,我不知道其他问题。然而,不同意这种方式太复杂。它做同样的事情:尝试并写入一个文件。如果成功,那么该目录不是只读的。 – AlainD 2017-09-07 15:55:26