Delphi 读取使用不同默认编码写入的文本文件

Delphi 读取使用不同默认编码写入的文本文件,delphi,encoding,delphi-xe7,Delphi,Encoding,Delphi Xe7,我有一个文本文件,它是使用TStringStream编写的,没有明确传递编码。该文件是由一台意大利计算机生成的 var Stream : TStringStream; begin Stream := TStringStream.Create('Test £'); try Stream.SaveToFile('.\test.txt'); finally Stream.Free; end; end; test.txt Test £ 我需要从具有不同语言环境设置

我有一个文本文件,它是使用
TStringStream
编写的,没有明确传递编码。该文件是由一台意大利计算机生成的

var
  Stream : TStringStream;
begin
  Stream := TStringStream.Create('Test £');
  try
    Stream.SaveToFile('.\test.txt');
  finally
    Stream.Free;
  end;
end;
test.txt

Test £
我需要从具有不同语言环境设置的计算机读取此文件,但得到的文本不同:

var
  Stream : TStringStream;
begin
  Stream := TStringStream.Create('');
  try
    Stream.LoadFromFile('.\test.txt');
    ShowMessage(Stream.DataString);
  finally
    Stream.Free;
  end;
end;
showmessage指令显示以下文本:

Test Ł
(请注意,
Ł

我尝试将
TEncoding.Unicode
TEncoding.UTF8
传递到
TStringStream
构造函数,但我得到了意外的字符串和错误,如:

目标多字节中不存在Unicode字符的映射 代码页

有没有办法识别源默认编码(考虑区域设置)并使用它从具有不同区域设置的计算机读取文件

我的意思是:

var
  Stream : TStringStream;
begin
  Stream := TStringStream.Create('');
  try
    Stream.LoadFromFile('.\test.txt', TEncoding.EncodingUsedByTheWriter);
    ShowMessage(Stream.DataString);
  finally
    Stream.Free;
  end;
end;

原则上,基本上不可能确定使用了哪个8位代码页。然而,你可以猜测,特别是如果你能接触到大量的词汇词典。要吸取的教训:永远不要使用传统的8位编码。始终使用Unicode。如果您知道源代码,。则不可能自动检测它(至少对于如此短的文本不可能)。考虑这个问题:你从一个人那里得到一个文件,包含“测试英镑”和一个包含“测试”的人B中的一个文件。这两个文件是二进制相同的,那么您如何知道哪一个是“Test&”,哪一个是“TestŁ”?您无法仅从文件内容来确定这一点。但是,如果您知道保存文件时使用的语言环境,可以使用:TEncoding.GetEncoding(CodePage)强制执行此操作。意大利通常使用的代码页是28591(ISO-8859-1)或1252(Windows-1252)。试试这两个值。@AndreasRejbrand:我会记住的!将来我将只使用
TEncoding.Unicode
:您不需要TEncoding.Unicode(它将使您的文件大小加倍)。您也可以使用TEncoding.UTF8(它也是Unicode,但采用8位编码而不是16位内定)。@Fabrizio只需确保在使用完
TEncoding.GetEncoding()
后,您从
TEncoding.GetEncoding()获得的
TEncoding
对象是免费的。采用
TEncoding
TStringStream
构造函数有一个可选的
AOwnsEncoding
参数
TStringStream
还有另一个构造函数,它有一个
ACodePage
参数,因此您不必直接调用
TEncoding.GetEncoding()
。原则上,根本不可能确定使用了哪个8位代码页。然而,你可以猜测,特别是如果你能接触到大量的词汇词典。要吸取的教训:永远不要使用传统的8位编码。始终使用Unicode。如果您知道源代码,。则不可能自动检测它(至少对于如此短的文本不可能)。考虑这个问题:你从一个人那里得到一个文件,包含“测试英镑”和一个包含“测试”的人B中的一个文件。这两个文件是二进制相同的,那么您如何知道哪一个是“Test&”,哪一个是“TestŁ”?您无法仅从文件内容来确定这一点。但是,如果您知道保存文件时使用的语言环境,可以使用:TEncoding.GetEncoding(CodePage)强制执行此操作。意大利通常使用的代码页是28591(ISO-8859-1)或1252(Windows-1252)。试试这两个值。@AndreasRejbrand:我会记住的!将来我将只使用
TEncoding.Unicode
:您不需要TEncoding.Unicode(它将使您的文件大小加倍)。您也可以使用TEncoding.UTF8(它也是Unicode,但采用8位编码而不是16位内定)。@Fabrizio只需确保在使用完
TEncoding.GetEncoding()
后,您从
TEncoding.GetEncoding()获得的
TEncoding
对象是免费的。采用
TEncoding
TStringStream
构造函数有一个可选的
AOwnsEncoding
参数
TStringStream
还有另一个构造函数,它有一个
aDepage
参数,因此您不必直接调用
TEncoding.GetEncoding()