分享

Delphi中TSearchRec的Attr有效值问题

 天已 2012-04-14
Delphi中TSearchRec的Attr有效值问题
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种类型的组合也不能找出全部的文件。通过分析发现,
我还找到了Windows中众多不同于以上7中Value值的文件,现将这些文件类型罗列如下:
-------------------------------------------------------------
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.其中文件的几种属性组合情况【此处没有像文件夹类型那样一一写成对应整数值】
只读
隐藏
存档
索引
压缩
加密
只读+隐藏
只读+存档
只读+索引
只读+压缩
只读+加密
只读+隐藏+存档
只读+隐藏+索引
只读+隐藏+压缩
只读+隐藏+加密
只读+隐藏+存档+索引
只读+隐藏+存档+压缩
只读+隐藏+存档+加密
文件可能有以下类型【用对应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来查找。以下提供了几个遍历文件有关的函数或方法:
  1. unit utFileSearch;  
  2. interface  
  3. uses  
  4.   Windows, SysUtils, Classes;  
  5.   { TODO : 从搜索记录中判断是否是子目录 }  
  6.   function IsValidDir(SearchRec:TSearchRec):Boolean;  
  7.   { TODO : 判断是不是实在的文件 }  
  8.   function IsRealFile(SearchRec:TSearchRec):Boolean;  
  9.   { TODO : 返回所有的文件名及其路径[不包括目录文件] 
  10.   MainPath:string; 为根目录 
  11.   var FoundResult:TStrings;为返回的文件列表结果集 
  12.   当找到的文件大于一个时返回True}  
  13.   function ListRealFile(MainPath:stringvar FoundResult:TStrings):Boolean;  
  14.   { TODO : 返回所有的文件夹名及其路径[既目录文件] 
  15.   MainPath:string; 为根目录 
  16.   var FoundResult:TStrings;为返回的文件列表结果集 
  17.   当找到的文件大于一个时返回True}  
  18.   function ListValidDir(MainPath:stringvar FoundResult:TStrings):Boolean;  
  19.   { TODO : 遍历指定文件类型的文件名及其路径 
  20.   MainPath:string; 为根目录 
  21.   FileExt:string; 为需要查找的文件扩展名,必须代点如‘.exe’ 
  22.   var FoundResult:TStrings;为返回的文件列表结果集 
  23.   当找到的文件大于一个时返回True}  
  24.   function ListExtFile(MainPath:string; FileExt:stringvar FoundResult:TStrings):Boolean;  
  25.   { TODO : 获取可写入的磁盘的列表}  
  26.   function GetDrives(var ResultList:TStrings):integer;  
  27.     
  28.   { TODO : 遍历指定文件类型的文件名及其路径[所有盘符下] 
  29.   FileExt:string; 为需要查找的文件扩展名,必须代点如‘.exe’ 
  30.   var FoundResult:TStrings;为返回的文件列表结果集 
  31.   当找到的文件大于一个时返回True}  
  32.   function ListAllExtFile(FileExt:stringvar FoundResult:TStrings):Boolean;  
  33. implementation  
  34. {将可写入数据的盘罗列出来,抛弃未知,光驱,路径不正确的}  
  35. function GetDrives(var ResultList:TStrings):integer;  
  36. var  
  37.   DriveNum: Integer;  
  38.   DriveBits: set of 0..25//假设最多有26个盘  
  39.   DriveType: UINT; //驱动器类型  
  40.   DriveName: string;  
  41. begin  
  42.   //获取全部Drivers并格式化到DriveBits里面  
  43.   Integer(DriveBits) := GetLogicalDrives;  
  44.   for DriveNum := 0 to 25 do  
  45.   begin  
  46.   //不在表里则放弃  
  47.   if not (DriveNum in DriveBits) then Continue;  
  48.   DriveName:= Char(DriveNum + Ord('A'))+ ':';  
  49.   DriveType:= GetDriveType(PCHAR(@DriveName[1])); //获得磁盘类型  
  50.   //清楚CDROM,未知,无效 和 network 类型的驱动器  
  51.   if (DriveType<>DRIVE_CDROM) and (DriveType<>0and  
  52.   (DriveType<>DRIVE_REMOTE) and (DriveType<>1then  
  53.   begin  
  54.   ResultList.Add(DriveName+'/');  
  55.   end;  
  56.   end;  
  57.   Result:=ResultList.Count;  
  58. end;  
  59. function IsValidDir(SearchRec:TSearchRec):Boolean;  
  60. begin  
  61.   { TODO : 文件类型为[16,31]和48,49,2064,2096的都是文件夹既目录 }  
  62.   if ( ((SearchRec.Attr>=16)and(SearchRec.Attr<=31)) or  
  63.   (SearchRec.Attr=48or (SearchRec.Attr=49or  
  64.   (SearchRec.Attr=50or (SearchRec.Attr=2064or  
  65.   (SearchRec.Attr=2066or (SearchRec.Attr=2096or  
  66.   (SearchRec.Attr=2098or (SearchRec.Attr=8208or  
  67.   (SearchRec.Attr=8210or (SearchRec.Attr=8240or  
  68.   (SearchRec.Attr=8242or (SearchRec.Attr=10256or  
  69.   (SearchRec.Attr=10258or (SearchRec.Attr=10288or  
  70.   (SearchRec.Attr=10290or (SearchRec.Attr=16400or  
  71.   (SearchRec.Attr=16402or (SearchRec.Attr=16432or  
  72.   (SearchRec.Attr=16434or (SearchRec.Attr=24624or  
  73.   (SearchRec.Attr=24626or (SearchRec.Attr=1243048) ) and  
  74.   ( SearchRec.Name<>'.' ) and (SearchRec.Name<>'..' )  
  75.   then Result:=True else Result:=False;  
  76. end;  
  77. function IsRealFile(SearchRec:TSearchRec):Boolean;  
  78. begin  
  79.   { TODO : 文件类型为1,2,3,4,6,7,32,33,34,35,36,38,39,128,2049,2080,2083,2086, 
  80.   8192,8193,8195,8224,8227,10241, 12582,16416,16419, 24577的都是实在的文件}  
  81.   if ( ((SearchRec.Attr>=1)and(SearchRec.Attr<=15)) or //[1,15]  
  82.   ((SearchRec.Attr>=32)and(SearchRec.Attr<40)) or //[32,40)  
  83.   (SearchRec.Attr=128or (SearchRec.Attr=2049or  
  84.   (SearchRec.Attr=2080)or (SearchRec.Attr=2083or  
  85.   (SearchRec.Attr=2086)or (SearchRec.Attr=8192or  
  86.   (SearchRec.Attr=8193)or (SearchRec.Attr=8195or  
  87.   (SearchRec.Attr=8224)or (SearchRec.Attr=8227or  
  88.   (SearchRec.Attr=10241)or (SearchRec.Attr=12582or  
  89.   (SearchRec.Attr=16416)or (SearchRec.Attr=16419or  
  90.   (SearchRec.Attr=24577) ) and  
  91.   (SearchRec.Name<>'.'and (SearchRec.Name<>'..')  
  92.   then Result:=True else Result:=False;  
  93. end;  
  94. function ListRealFile(MainPath:stringvar FoundResult:TStrings):Boolean;  
  95. var SearchRec:TSearchRec;  
  96.   Dir:TStrings; //用TStrings记录找到的文件的路径  
  97.   i:Integer;  
  98. begin  
  99.   MainPath:=Trim(MainPath);  
  100.   if MainPath='' then  
  101.   begin  
  102.   Result:=False;  
  103.   Exit;  
  104.   end;  
  105.   Dir:=TStringList.Create;  
  106.   FindFirst(MainPath+'*.*',faAnyFile, SearchRec);  
  107.   //将子目录放入Dir中  
  108.   if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);  
  109.   //将文件放入结果集中  
  110.   if IsRealFile(SearchRec) then FoundResult.Add(MainPath+SearchRec.Name);  
  111.   //找完第一条后继续寻找  
  112.   Repeat  
  113.   i:=FindNext(SearchRec);  
  114.   if i=0 then  
  115.   begin  
  116.   if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);  
  117.   if IsRealFile(SearchRec) then FoundResult.Add(MainPath+SearchRec.Name);  
  118.   end;  
  119.   Until i<>0;  
  120.   //释放由FindFirst开启的资源  
  121.   FindClose(SearchRec);  
  122.   //这是递归部分,查找各子目录。  
  123.   for i:=0 to Dir.Count-1 do  
  124.   ListRealFile(MainPath+Dir.Strings[i]+'/',FoundResult);  
  125.   //资源释放  
  126.   Dir.Free;  
  127.   if FoundResult.Count>0 then Result:=True else Result:=False;  
  128. end;  
  129. function ListValidDir(MainPath:stringvar FoundResult:TStrings):Boolean;  
  130. var SearchRec:TSearchRec;  
  131.   Dir:TStrings; //用TStrings记录找到的文件的路径  
  132.   i:Integer;  
  133. begin  
  134.   MainPath:=Trim(MainPath);  
  135.   if MainPath='' then  
  136.   begin  
  137.   Result:=False;  
  138.   Exit;  
  139.   end;  
  140.   Dir:=TStringList.Create;  
  141.   FindFirst(MainPath+'*.*',faAnyFile, SearchRec);  
  142.   //将递归时还要用的子目录放入Dir中  
  143.   if IsValidDir(SearchRec) then  
  144.   begin  
  145.   Dir.Add(SearchRec.Name);  
  146.   //收集结果集  
  147.   FoundResult.Add(MainPath+SearchRec.Name);  
  148.   end;  
  149.   //找完第一条后继续寻找  
  150.   Repeat  
  151.   i:=FindNext(SearchRec);  
  152.   if (i=0and IsValidDir(SearchRec) then  
  153.   begin  
  154.   Dir.Add(SearchRec.Name);  
  155.   FoundResult.Add(MainPath+SearchRec.Name);  
  156.   end;  
  157.   Until i<>0;  
  158.   //释放由FindFirst开启的资源  
  159.   FindClose(SearchRec);  
  160.   //这是递归部分,查找各子目录。  
  161.   for i:=0 to Dir.Count-1 do  
  162.   ListValidDir(MainPath+Dir.Strings[i]+'/',FoundResult);  
  163.   //资源释放  
  164.   Dir.Free;  
  165.   if FoundResult.Count>0 then Result:=True else Result:=False;  
  166. end;  
  167. function ListExtFile(MainPath:string; FileExt:stringvar FoundResult:TStrings):Boolean;  
  168. var SearchRec:TSearchRec;  
  169.   Dir:TStrings; //用TStrings记录找到的文件的路径  
  170.   i:Integer;  
  171. begin  
  172.   MainPath:=Trim(MainPath);  
  173.   FileExt:=Trim(FileExt);  
  174.   //检查输入合法性  
  175.   if (MainPath=''or (FileExt=''then  
  176.   begin  
  177.   Result:=False;  
  178.   Exit;  
  179.   end;  
  180.   Dir:=TStringList.Create;  
  181.   FindFirst(MainPath+'*.*',faAnyFile, SearchRec);  
  182.   //将子目录放入Dir中  
  183.   if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);  
  184.   //将文件放入结果集中  
  185.   if IsRealFile(SearchRec) then  
  186.   if ExtractFileExt(SearchRec.Name)=FileExt then  
  187.   FoundResult.Add(MainPath+SearchRec.Name);  
  188.   //找完第一条后继续寻找  
  189.   Repeat  
  190.   i:=FindNext(SearchRec);  
  191.   if i=0 then  
  192.   begin  
  193.   if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);  
  194.   if IsRealFile(SearchRec) then  
  195.   if ExtractFileExt(SearchRec.Name)=FileExt then  
  196.   FoundResult.Add(MainPath+SearchRec.Name);  
  197.   end;  
  198.   Until i<>0;  
  199.   //释放由FindFirst开启的资源  
  200.   FindClose(SearchRec);  
  201.   //这是递归部分,查找各子目录。  
  202.   for i:=0 to Dir.Count-1 do  
  203.   ListExtFile(MainPath+Dir.Strings[i]+'/',FileExt,FoundResult);  
  204.   //资源释放  
  205.   Dir.Free;  
  206.   if FoundResult.Count>0 then Result:=True else Result:=False;  
  207. end;  
  208. function ListAllExtFile(FileExt:stringvar FoundResult:TStrings):Boolean;  
  209. var SearchRec:TSearchRec;  
  210.   Dir,MainDir:TStrings;  
  211.   i,j:Integer;  
  212.   function GetDrives(var ResultList:TStrings):integer;  
  213.   var  
  214.   DriveNum: Integer;  
  215.   DriveBits: set of 0..25;  
  216.   DriveType: UINT;  
  217.   DriveName: string;  
  218.   begin  
  219.   Integer(DriveBits) := GetLogicalDrives;  
  220.   for DriveNum := 0 to 25 do  
  221.   begin  
  222.   if not (DriveNum in DriveBits) then Continue;  
  223.   DriveName:= Char(DriveNum + Ord('A'))+ ':';  
  224.   DriveType:= GetDriveType(PCHAR(@DriveName[1]));  
  225.   if (DriveType<>DRIVE_CDROM) and (DriveType<>0and  
  226.   (DriveType<>DRIVE_REMOTE) and (DriveType<>1then  
  227.   begin  
  228.   ResultList.Add(DriveName+'/');  
  229.   end;  
  230.   end;  
  231.   Result:=ResultList.Count;  
  232.   end;  
  233. begin  
  234.   FileExt:=Trim(FileExt);  
  235.   if FileExt='' then  
  236.   begin  
  237.   Result:=False;  
  238.   Exit;  
  239.   end;  
  240.   MainDir:=TStringList.Create;  
  241.   if GetDrives(MainDir)>0 then  
  242.   begin  
  243.   for j:=0 to MainDir.Count-1 do  
  244.   begin  
  245.   Dir:=TStringList.Create;  
  246.   FindFirst(MainDir.Strings[j]+'*.*',faAnyFile, SearchRec);  
  247.   if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);  
  248.   if IsRealFile(SearchRec) then  
  249.   if ExtractFileExt(SearchRec.Name)=FileExt then  
  250.   FoundResult.Add(MainDir.Strings[j]+SearchRec.Name);  
  251.   Repeat  
  252.   i:=FindNext(SearchRec);  
  253.   if i=0 then  
  254.   begin  
  255.   if IsValidDir(SearchRec) then Dir.Add(SearchRec.Name);  
  256.   if IsRealFile(SearchRec) then  
  257.   if ExtractFileExt(SearchRec.Name)=FileExt then  
  258.   FoundResult.Add(MainDir.Strings[j]+SearchRec.Name);  
  259.   end;  
  260.   Until i<>0;  
  261.   FindClose(SearchRec);  
  262.   for i:=0 to Dir.Count-1 do  
  263.   ListExtFile(MainDir.Strings[j]+Dir.Strings[i]+'/',FileExt,FoundResult);  
  264.   Dir.Free;  
  265.   end;  
  266.   if FoundResult.Count>0 then Result:=True else Result:=False;  
  267.   end  
  268.   else  
  269.   Result:=False;  
  270.   MainDir.Free;  
  271. end;  
  272. end.  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多