2010-10-15 106 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