Delphi文件夹扫描程序 - Unicode文件夹名称

时间:2009-01-19 08:24:26

标签: delphi unicode recursion

哟。

我需要扫描目录及其子文件夹,我使用了FindFirst和FindNext程序,但TSearchRec的Name属性是一个字符串,因此unicode文件夹名称(希伯来语,阿拉伯语等)是'?????'在Name属性中。

我尝试使用TntComponent,使用WideFindFirst,WideFindNext和TSearchRecW。 但我仍然得到??????对于文件夹名称。

 Flname:=WideExtractFileName(FileSpec);
 validres := WideFindFirst(FileSpec+'\*', faDirectory, SearchRec);
 AssignFile(LogFile, ResultFilePath);

 while validres=0 do begin
   if (SearchRec.Attr and faDirectory>0) and (SearchRec.Name[1]<>'.') then begin
     {invalid entry Findnext returns}
     Append(LogFile);
     WriteLn(LogFile, FileSpec+'\'+LowerCase(SearchRec.Name));
     CloseFile(LogFile);
     DirScan(FileSpec+'\'+SearchRec.Name, ResultFilePath)
   end;
   validres:=WideFindNext(SearchRec);
 end;
 WideFindClose(SearchRec);

4 个答案:

答案 0 :(得分:4)

Delphi使用WideString支持编译器中的unicode。

但是你会遇到以下问题:

  • Delphi&lt; 2009年在他们的VCL中不支持unicode。
  • 许多API映射都是在API的ANSI(OpenFileA)变体上完成的。
  • delphi编译器会将WideStrings转换为很多字符串,所以要非常清楚它们。

如果您使用原始unicode windows api,它将起作用。

因此,FindFirst使用delphi映射到FindFirstFileA变体的api FindFirstFile,您需要直接调用FindFirstW。

所以你有两个选择。

  1. 升级到Delphi 2009并为您完成了大量的unicode映射
    • 编写自己的unicode映射函数
  2. 对于文本文件编写,您可以使用Primoz Gabrijelcic(又名gabr)的GpTextFileGpTextSteam,它们具有unicode支持。

    她是打开带有unicode文件名的文件的示例:

    function OpenLongFileName(const ALongFileName: WideString; SharingMode: DWORD): THandle;  overload;
    begin
      if CompareMem(@(WideCharToString(PWideChar(ALongFileName))[1]), @('\\'[1]), 2) then
        { Allready an UNC path }
        Result := CreateFileW(PWideChar(ALongFileName), GENERIC_READ, SharingMode, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
      else
        Result := CreateFileW(PWideChar('\\?\' + ALongFileName), GENERIC_READ, SharingMode, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    end;
    
    function CreateLongFileName(const ALongFileName: WideString; SharingMode: DWORD): THandle; overload;
    begin
      if CompareMem(@(WideCharToString(PWideChar(ALongFileName))[1]), @('\\'[1]), 2) then
        { Allready an UNC path }
        Result := CreateFileW(PWideChar(ALongFileName), GENERIC_WRITE, SharingMode, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
      else
        Result := CreateFileW(PWideChar('\\?\' + ALongFileName), GENERIC_WRITE, SharingMode, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    end;
    

    我已经使用过这些函数,因为ANSI api的路径限制为254个字符,如果我没弄错的话,unicode的限制为2 ^ 16个字符。

    获得文件句柄后,只需调用常规的ReadFile delphi api映射,即可从文件中读取数据。

答案 1 :(得分:2)

2009年之前的Delphi版本对unicode支持非常有限。所以,如果你真的想要unicode,那么我强烈建议你升级到2009年。在2009年,默认字符串是unicode。

你说你仍然有宽版本的垃圾字符。您是否尝试使用调试器检查值? 2009年德尔福之前的vcl无法显示unicode字符。

答案 2 :(得分:0)

一些更新..如果我在SearchRec.Name上使用UTF8Encode,我会得到unicode字符串! 接下来的问题是我使用的TFileStream。我找不到它的WideString版本(文件名)。

答案 3 :(得分:0)

您可以使用CreateFileW打开文件并获取句柄,然后使用THandleStream而不是TFileStream来读取文件。

Tnt Unicode(现在是TMS Unicode)有一个TTntFileStream,可以打开基于widestring的文件。 正如Gamecat所说,如果你想做unicode,你应该真正升级到Delphi 2009.(一般来说很棒的发布)