1

よう。

ディレクトリとそのサブフォルダをスキャンする必要があります。FindFirst および FindNext プロシージャを使用しましたが、TSearchRec の Name プロパティは文字列であるため、Unicode フォルダ名 (ヘブライ語、アラビア語など) は「?????」です。名前プロパティで。

WideFindFirst、WideFindNext、TSearchRecW で TntComponent を使用してみました。しかし、私はまだ??????を取得します フォルダ名用。

 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

4 に答える 4

4

Delphiは、WideStringを使用して、コンパイラでUnicodeをサポートします。

ただし、次の問題が発生します。

  • Delphi <2009は、VCLでUnicodeをサポートしていません。
  • 多くのAPIマッピングは、APIのANSI(たとえば、OpenFileA)バリアントで行われます。
  • delphiコンパイラは、WideStringを文字列に大量に変換するため、それらについて非常に明確にします。

生のUnicodeウィンドウAPIを使用する場合に機能します。

したがって、FindFirstは、デルファイがFindFirstFileAバリアントにマップするAPI FindFirstFileを使用し、FindFirstWを直接呼び出す必要があります。

したがって、2つのオプションがあります。

  1. Delphi 2009にアップグレードして、多くのUnicodeマッピングを実行してください
    • 独自のUnicodeマッピング関数を作成する

テキストファイルの書き込みには、Primoz Gabrijelcic(別名gabr)のGpTextFileまたはGpTextSteamを使用できる場合があり、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マッピングを呼び出すだけで、ファイルからデータを読み取ることができます。

于 2009-01-19T10:05:03.097 に答える
2

2009 年より前のバージョンの Delphi では、Unicode のサポートが非常に限られています。したがって、本当に Unicode が必要な場合は、2009 にアップグレードすることを強くお勧めします。2009 では、デフォルトの文字列は unicode です。

ワイド版でもゴミキャラが出るって言ってたけど。デバッガーで値を検査しようとしましたか? 2009 年より前の Delphi の vcl は、Unicode 文字を表示できません。

于 2009-01-19T08:59:48.327 に答える
0

CreateFileWを使用してファイルを開き、ハンドルを取得してから、TFileStreamの代わりにTHandleStreamを使用してファイルを読み取ることができます。

Tnt Unicode(現在はTMS Unicode)には、ワイドストリングに基づいてファイルを開くことができるTTntFileStreamがあります。そしてGamecatが述べたように、ユニコードを実行したい場合は、実際にDelphi 2009にアップグレードする必要があります。(一般的に素晴らしいリリース)

于 2009-01-19T09:58:51.080 に答える
0

いくつかの更新.. SearchRec.Name で UTF8Encode を使用すると、Unicode 文字列が取得されます。次の問題は、私が使用する TFileStream です。そのための WideString バージョンが見つかりませんでした (ファイル名用)。

于 2009-01-19T09:40:45.080 に答える