哟。
我需要扫描目录及其子文件夹,我使用了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);
答案 0 :(得分:4)
Delphi使用WideString支持编译器中的unicode。
但是你会遇到以下问题:
如果您使用原始unicode windows api,它将起作用。
因此,FindFirst使用delphi映射到FindFirstFileA变体的api FindFirstFile,您需要直接调用FindFirstW。
所以你有两个选择。
对于文本文件编写,您可以使用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映射,即可从文件中读取数据。
答案 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.(一般来说很棒的发布)