gpt4 book ai didi

delphi - 为什么非Unicode页面为韩语(949)时ReadLn会误解UTF8文本?

转载 作者:行者123 更新时间:2023-12-01 21:48:16 25 4
gpt4 key购买 nike

在Delphi XE2中,使用AssignFileReadLn()例程,当系统语言环境为英语时,我只能读取和显示Unicode字符(来自UTF8编码文件)。

哪里失败
如果我将非Unicode应用程序的系统语言环境设置为韩语(我认为是代码页949)并重复相同的读取操作,则我的一些UTF8多字节对将替换为$3F。这仅适用于使用ReadLn,不适用于使用TFile.ReadAllText(aFilename, TEncoding.UTF8)TFileStream.Read()的情况。

考试
1.我创建一个文本文件,UTF8 w / o BOM(Notepad ++),其中包含以下字符(在第二行显示十六进制等效项):

테스트
ed 85 8c ec 8a a4 ed 8a b8



用TMemo控件编写一个Delphi XE 2 Windows窗体应用程序:

procedure TForm1.ReadFile(aFilename:string);
var
gFile : TextFile;
gLine : RawByteString;
gWideLine : string;
begin
AssignFile(gFile, aFilename);
try
Reset(gFile);
Memo1.Clear;
while not EOF(gFile) do
begin
ReadLn(gFile, gLine);
gWideLine := UTF8ToWideString(gLine);
Memo1.Lines.Add(gWideLine);
end;
finally
CloseFile(gFile);
end;
end;

在执行 gLine对话之前,我检查 UTF8ToWideString的内容,在英语/美国语言环境下,它是:

$ED $85 $8C $EC $8A $A4 $ED $8A $B8


顺便说一句,如果我用BOM读取同一文件,则会得到正确的3字节前同步码,并且执行UTF8解码时的输出是相同的。到目前为止一切正常!


切换Windows 7(x64)以将韩语用作不支持Unicode的应用程序的代码页(“区域和语言”->“管理”选项卡->更改系统区域设置->韩语(韩国)),重新启动计算机。
读取与上述应用程序相同的文件(不带BOM的UTF8),并且 gLine现在具有十六进制值:

$3F $8C $EC $8A $A4 $3F $3F

TMemo中的输出:?�스??
假设 ReadLn()(和 Read()试图将UTF8序列映射为韩文多字节序列(即试图解释$ ED $ 85,不能解释为$ 3F的子对象)。
使用 TFileStream精确读取期望的字节数(9 w / o BOM),并且内存中的十六进制现在正好是:

$ED $85 $8C $EC $8A $A4 $ED $8A $B8

TMemo中的输出:테스트(完美!)


问题:懒惰-我有很多旧式例程逐行解析潜在的大文件,我想确保不需要编写例程即可手动读取,直到每个文件都有新行。

问题:


为什么 Read()不返回文件中找到的确切字节字符串?是因为我使用的是 TextFile类型,所以Delphi使用非Unicode代码页进行一定程度的解释吗?
是否有内置的方式逐行读取UTF8编码的文件?


更新:

刚遇到Rob Kennedy对 this post的解决方案,这使我重新引入了TStreamReader,该解决方案逐行回答了有关正常读取UTF8文件的问题。

最佳答案

是否有内置的方式逐行读取UTF8编码的文件?


使用TStreamReader。它具有ReadLine()方法。

    procedure TForm1.ReadFile(aFilename:string);
var
gFile : TStreamReader;
gLine : string;
begin
Memo1.Clear;
gFile := TStreamReader.Create(aFilename, TEncoding.UTF8, True);
try
while not gFile.EndOfStream do
begin
gLine := gFile.ReadLine;
Memo1.Lines.Add(gLine);
end;
finally
gFile.Free;
end;
end;


话虽如此,这个特定的例子可以大大简化:

    procedure TForm1.ReadFile(aFilename:string);
begin
Memo1.Lines.LoadFromFile(aFilename, TEncoding.UTF8);
end;

关于delphi - 为什么非Unicode页面为韩语(949)时ReadLn会误解UTF8文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29186026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com