Delphi中的TSearchRec結構中有Attr的屬性。從幫助文檔可知Attr只提供了7中類型的文件屬性值:
-------------------------------------------------------------
Constant Value Description Linux Meaning
-------------------------------------------------------------
faReadOnly 1 Read-only files Current user does not have write access.
faHidden 2 Hidden files File name begins with ".".
faSysFile 4 System files File is socket, symbolic link, device file, or FIFO.
faVolumeID 8 Volume ID files Not used.
faDirectory 16 Directory files Directory.
faArchive 32 Archive files Not used.
faSymLink 64 Symbolic link File is a symbolic link.
faAnyFile 71 Any file Any file.
-------------------------------------------------------------
而實際上,Windows中遠不只這幾種類型的文件。當我們通過判斷Attr值來查找制定類型的文件時如果用以上7中值查找我們會漏掉很多類型的
文件,因為很多文件類型TSearchRec.Attr都沒有提供,且即便是用faAnyFile或者用這7種類型的組合也不能找出全部的文件。通過分析發(fā)現(xiàn),
我還找到了Windows中眾多不同于以上7中Value值的文件,現(xiàn)將這些文件類型羅列如下:
-------------------------------------------------------------
1.其中文件夾(即目錄)的幾種屬性組合情況【壓縮和加密不可同時存在】
8208 NULL
8208 只讀
8210 隱藏
8240 存檔
16 索引
10256 壓縮
24624 加密
8242 只讀+隱藏
8240 只讀+存檔
16 只讀+索引
10256 只讀+壓縮
24624 只讀+加密
8242 只讀+隱藏+存檔
18 只讀+隱藏+索引
10258 只讀+隱藏+壓縮
24626 只讀+隱藏+加密
50 只讀+隱藏+存檔+索引
10290 只讀+隱藏+存檔+壓縮
24626 只讀+隱藏+存檔+加密
2098 只讀+隱藏+存檔+索引+壓縮
16434 只讀+隱藏+存檔+索引+加密
48 只讀+存檔+索引
10288 只讀+存檔+壓縮
24624 只讀+存檔+加密
2096 只讀+存檔+索引+壓縮
16432 只讀+存檔+索引+加密
2096 只讀+索引+壓縮
16432 只讀+索引+加密
8242 隱藏+存檔
18 隱藏+索引
10258 隱藏+壓縮
24626 隱藏+加密
50 隱藏+存檔+索引
10290 隱藏+存檔+壓縮
24626 隱藏+存檔+加密
2098 隱藏+索引+壓縮
16434 隱藏+索引+加密
48 存檔+索引
10288 存檔+壓縮
24624 存檔+加密
2096 存檔+索引+壓縮
16432 存檔+索引+加密
2096 索引+壓縮
16400 索引+加密
文件夾(即目錄)可能有以下類型【用對應Value值表示】
16,17,18,19,20,21,22,23,48,49,50,2064,2066,2096,2098,8208,8210,8240,8242,10256,10258,10288,10290,16400,16402,16432,16434,2462
4,24626,1243048
-------------------------------------------------------------
2.其中文件的幾種屬性組合情況【此處沒有像文件夾類型那樣一一寫成對應整數(shù)值】
只讀
隱藏
存檔
索引
壓縮
加密
只讀+隱藏
只讀+存檔
只讀+索引
只讀+壓縮
只讀+加密
只讀+隱藏+存檔
只讀+隱藏+索引
只讀+隱藏+壓縮
只讀+隱藏+加密
只讀+隱藏+存檔+索引
只讀+隱藏+存檔+壓縮
只讀+隱藏+存檔+加密
文件可能有以下類型【用對應Value值表示】
1,2,3,4,6,7,32,33,34,35,36,38,39,128,2049,2080,2083,2086,8192,8193,8195,8224,8227,10241, 12582,16416,16419,
24577,16416,16419, 24577
后記:Windows中的文件大部分都在提供的7種類型中,但是如果我們要搜索文件是硬盤上的所有類型的文件時用提供的7種類型或其組合是無法
找出來的,我們只能通過盤讀SearchRec.Attr>0的方式找出所有文件,當我們要查找這7種文件類型以外的某種指定類型的文件時我們只能通過
制定其Value來查找。以下提供了幾個遍歷文件有關的函數(shù)或方法:
- unit utFileSearch;
- interface
- uses
- Windows, SysUtils, Classes;
- { TODO : 從搜索記錄中判斷是否是子目錄 }
- function IsValidDir(SearchRec:TSearchRec):Boolean;
- { TODO : 判斷是不是實在的文件 }
- function IsRealFile(SearchRec:TSearchRec):Boolean;
- { TODO : 返回所有的文件名及其路徑[不包括目錄文件]
- MainPath:string; 為根目錄
- var FoundResult:TStrings;為返回的文件列表結果集
- 當找到的文件大于一個時返回True}
- function ListRealFile(MainPath:string; var FoundResult:TStrings):Boolean;
- { TODO : 返回所有的文件夾名及其路徑[既目錄文件]
- MainPath:string; 為根目錄
- var FoundResult:TStrings;為返回的文件列表結果集
- 當找到的文件大于一個時返回True}
- function ListValidDir(MainPath:string; var FoundResult:TStrings):Boolean;
- { TODO : 遍歷指定文件類型的文件名及其路徑
- MainPath:string; 為根目錄
- FileExt:string; 為需要查找的文件擴展名,必須代點如‘.exe’
- var FoundResult:TStrings;為返回的文件列表結果集
- 當找到的文件大于一個時返回True}
- function ListExtFile(MainPath:string; FileExt:string; var FoundResult:TStrings):Boolean;
- { TODO : 獲取可寫入的磁盤的列表}
- function GetDrives(var ResultList:TStrings):integer;
-
- { TODO : 遍歷指定文件類型的文件名及其路徑[所有盤符下]
- FileExt:string; 為需要查找的文件擴展名,必須代點如‘.exe’
- var FoundResult:TStrings;為返回的文件列表結果集
- 當找到的文件大于一個時返回True}
- function ListAllExtFile(FileExt:string; var FoundResult:TStrings):Boolean;
- implementation
- {將可寫入數(shù)據(jù)的盤羅列出來,拋棄未知,光驅,路徑不正確的}
- function GetDrives(var ResultList:TStrings):integer;
- var
- DriveNum: Integer;
- DriveBits: set of 0..25; //假設最多有26個盤
- DriveType: UINT; //驅動器類型
- DriveName: string;
- begin
- //獲取全部Drivers并格式化到DriveBits里面
- Integer(DriveBits) := GetLogicalDrives;
- for DriveNum := 0 to 25 do
- begin
- //不在表里則放棄
- if not (DriveNum in DriveBits) then Continue;
- DriveName:= Char(DriveNum + Ord('A'))+ ':';
- DriveType:= GetDriveType(PCHAR(@DriveName[1])); //獲得磁盤類型
- //清楚CDROM,未知,無效 和 network 類型的驅動器
- if (DriveType<>DRIVE_CDROM) and (DriveType<>0) and
- (DriveType<>DRIVE_REMOTE) and (DriveType<>1) then
- begin
- ResultList.Add(DriveName+'/');
- end;
- end;
- Result:=ResultList.Count;
- end;
- function IsValidDir(SearchRec:TSearchRec):Boolean;
- begin
- { TODO : 文件類型為[16,31]和48,49,2064,2096的都是文件夾既目錄 }
- if ( ((SearchRec.Attr>=16)and(SearchRec.Attr<=31)) or
- (SearchRec.Attr=48) or (SearchRec.Attr=49) or
- (SearchRec.Attr=50) or (SearchRec.Attr=2064) or
- (SearchRec.Attr=2066) or (SearchRec.Attr=2096) or
- (SearchRec.Attr=2098) or (SearchRec.Attr=8208) or
- (SearchRec.Attr=8210) or (SearchRec.Attr=8240) or
- (SearchRec.Attr=8242) or (SearchRec.Attr=10256) or
- (SearchRec.Attr=10258) or (SearchRec.Attr=10288) or
- (SearchRec.Attr=10290) or (SearchRec.Attr=16400) or
- (SearchRec.Attr=16402) or (SearchRec.Attr=16432) or
- (SearchRec.Attr=16434) or (SearchRec.Attr=24624) or
- (SearchRec.Attr=24626) or (SearchRec.Attr=1243048) ) and
- ( SearchRec.Name<>'.' ) and (SearchRec.Name<>'..' )
- then Result:=True else Result:=False;
- end;
- function IsRealFile(SearchRec:TSearchRec):Boolean;
- begin
- { TODO : 文件類型為1,2,3,4,6,7,32,33,34,35,36,38,39,128,2049,2080,2083,2086,
- 8192,8193,8195,8224,8227,10241, 12582,16416,16419, 24577的都是實在的文件}
- if ( ((SearchRec.Attr>=1)and(SearchRec.Attr<=15)) or //[1,15]
- ((SearchRec.Attr>=32)and(SearchRec.Attr<40)) or //[32,40)
- (SearchRec.Attr=128) or (SearchRec.Attr=2049) or
- (SearchRec.Attr=2080)or (SearchRec.Attr=2083) or
- (SearchRec.Attr=2086)or (SearchRec.Attr=8192) or
- (SearchRec.Attr=8193)or (SearchRec.Attr=8195) or
- (SearchRec.Attr=8224)or (SearchRec.Attr=8227) or
- (SearchRec.Attr=10241)or (SearchRec.Attr=12582) or
- (SearchRec.Attr=16416)or (SearchRec.Attr=16419) or
- (SearchRec.Attr=24577) ) and
- (SearchRec.Name<>'.') and (SearchRec.Name<>'..')
- then Result:=True else Result:=False;
- end;
- function ListRealFile(MainPath:string; var FoundResult:TStrings):Boolean;
- var SearchRec:TSearchRec;
- Dir:TStrings; //用TStrings記錄找到的文件的路徑
- i:Integer;
- begin
- MainPath:=Trim(MainPath);
- if MainPath='' then
- begin
- Result:=False;
- Exit;
- end;
- Dir:=TStringList.Create;
- FindFirst(MainPath+'*.*',faAnyFile, SearchRec);
- //將子目錄放入Dir中
- if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);
- //將文件放入結果集中
- if IsRealFile(SearchRec) then FoundResult.Add(MainPath+SearchRec.Name);
- //找完第一條后繼續(xù)尋找
- Repeat
- i:=FindNext(SearchRec);
- if i=0 then
- begin
- if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);
- if IsRealFile(SearchRec) then FoundResult.Add(MainPath+SearchRec.Name);
- end;
- Until i<>0;
- //釋放由FindFirst開啟的資源
- FindClose(SearchRec);
- //這是遞歸部分,查找各子目錄。
- for i:=0 to Dir.Count-1 do
- ListRealFile(MainPath+Dir.Strings[i]+'/',FoundResult);
- //資源釋放
- Dir.Free;
- if FoundResult.Count>0 then Result:=True else Result:=False;
- end;
- function ListValidDir(MainPath:string; var FoundResult:TStrings):Boolean;
- var SearchRec:TSearchRec;
- Dir:TStrings; //用TStrings記錄找到的文件的路徑
- i:Integer;
- begin
- MainPath:=Trim(MainPath);
- if MainPath='' then
- begin
- Result:=False;
- Exit;
- end;
- Dir:=TStringList.Create;
- FindFirst(MainPath+'*.*',faAnyFile, SearchRec);
- //將遞歸時還要用的子目錄放入Dir中
- if IsValidDir(SearchRec) then
- begin
- Dir.Add(SearchRec.Name);
- //收集結果集
- FoundResult.Add(MainPath+SearchRec.Name);
- end;
- //找完第一條后繼續(xù)尋找
- Repeat
- i:=FindNext(SearchRec);
- if (i=0) and IsValidDir(SearchRec) then
- begin
- Dir.Add(SearchRec.Name);
- FoundResult.Add(MainPath+SearchRec.Name);
- end;
- Until i<>0;
- //釋放由FindFirst開啟的資源
- FindClose(SearchRec);
- //這是遞歸部分,查找各子目錄。
- for i:=0 to Dir.Count-1 do
- ListValidDir(MainPath+Dir.Strings[i]+'/',FoundResult);
- //資源釋放
- Dir.Free;
- if FoundResult.Count>0 then Result:=True else Result:=False;
- end;
- function ListExtFile(MainPath:string; FileExt:string; var FoundResult:TStrings):Boolean;
- var SearchRec:TSearchRec;
- Dir:TStrings; //用TStrings記錄找到的文件的路徑
- i:Integer;
- begin
- MainPath:=Trim(MainPath);
- FileExt:=Trim(FileExt);
- //檢查輸入合法性
- if (MainPath='') or (FileExt='') then
- begin
- Result:=False;
- Exit;
- end;
- Dir:=TStringList.Create;
- FindFirst(MainPath+'*.*',faAnyFile, SearchRec);
- //將子目錄放入Dir中
- if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);
- //將文件放入結果集中
- if IsRealFile(SearchRec) then
- if ExtractFileExt(SearchRec.Name)=FileExt then
- FoundResult.Add(MainPath+SearchRec.Name);
- //找完第一條后繼續(xù)尋找
- Repeat
- i:=FindNext(SearchRec);
- if i=0 then
- begin
- if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);
- if IsRealFile(SearchRec) then
- if ExtractFileExt(SearchRec.Name)=FileExt then
- FoundResult.Add(MainPath+SearchRec.Name);
- end;
- Until i<>0;
- //釋放由FindFirst開啟的資源
- FindClose(SearchRec);
- //這是遞歸部分,查找各子目錄。
- for i:=0 to Dir.Count-1 do
- ListExtFile(MainPath+Dir.Strings[i]+'/',FileExt,FoundResult);
- //資源釋放
- Dir.Free;
- if FoundResult.Count>0 then Result:=True else Result:=False;
- end;
- function ListAllExtFile(FileExt:string; var FoundResult:TStrings):Boolean;
- var SearchRec:TSearchRec;
- Dir,MainDir:TStrings;
- i,j:Integer;
- function GetDrives(var ResultList:TStrings):integer;
- var
- DriveNum: Integer;
- DriveBits: set of 0..25;
- DriveType: UINT;
- DriveName: string;
- begin
- Integer(DriveBits) := GetLogicalDrives;
- for DriveNum := 0 to 25 do
- begin
- if not (DriveNum in DriveBits) then Continue;
- DriveName:= Char(DriveNum + Ord('A'))+ ':';
- DriveType:= GetDriveType(PCHAR(@DriveName[1]));
- if (DriveType<>DRIVE_CDROM) and (DriveType<>0) and
- (DriveType<>DRIVE_REMOTE) and (DriveType<>1) then
- begin
- ResultList.Add(DriveName+'/');
- end;
- end;
- Result:=ResultList.Count;
- end;
- begin
- FileExt:=Trim(FileExt);
- if FileExt='' then
- begin
- Result:=False;
- Exit;
- end;
- MainDir:=TStringList.Create;
- if GetDrives(MainDir)>0 then
- begin
- for j:=0 to MainDir.Count-1 do
- begin
- Dir:=TStringList.Create;
- FindFirst(MainDir.Strings[j]+'*.*',faAnyFile, SearchRec);
- if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);
- if IsRealFile(SearchRec) then
- if ExtractFileExt(SearchRec.Name)=FileExt then
- FoundResult.Add(MainDir.Strings[j]+SearchRec.Name);
- Repeat
- i:=FindNext(SearchRec);
- if i=0 then
- begin
- if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);
- if IsRealFile(SearchRec) then
- if ExtractFileExt(SearchRec.Name)=FileExt then
- FoundResult.Add(MainDir.Strings[j]+SearchRec.Name);
- end;
- Until i<>0;
- FindClose(SearchRec);
- for i:=0 to Dir.Count-1 do
- ListExtFile(MainDir.Strings[j]+Dir.Strings[i]+'/',FileExt,FoundResult);
- Dir.Free;
- end;
- if FoundResult.Count>0 then Result:=True else Result:=False;
- end
- else
- Result:=False;
- MainDir.Free;
- end;
- end.