如何使用Delphi XE的TEncoding将Cyrillic或ShiftJis文本保存到文件?

3

我正在尝试使用Delphi XE将一些文本行保存到与我的系统不同的代码页,例如Cyrillic到TFileStream中。但是我找不到任何可以生成那些编码文件的代码示例?

我尝试使用与TStrings.SaveToStream相同的代码,但我不确定我是否正确实现了它(例如WriteBom部分),想知道其他人如何实现。这是我的代码:

FEncoding := TEncoding.GetEncoding(1251);
FFilePool := TObjectDictionary<string,TFileStream>.Create([doOwnsValues]);

//...

procedure WriteToFile(const aFile, aText: string);
var
  Preamble, Buffer: TBytes;
begin
  // Create the file if it doesn't exist
  if not FFilePool.ContainsKey(aFile) then
  begin
    // Create the file
    FFilePool.Add(aFile, TFileStream.Create(aFile, fmCreate));
    // Write the BOM
    Preamble := FEncoding.GetPreamble;
    if Length(Preamble) > 0 then
     FFilePool[aFile].WriteBuffer(Preamble[0], Length(Preamble));
  end;
  // Write to the file
  Buffer := FEncoding.GetBytes(aText);
  FFilePool[aFile].WriteBuffer(Buffer[0], Length(Buffer));
end;

提前感谢你。


1
为什么不让我们看看你的代码,然后我们可以评论呢?但我会说 ANSI Cyrillic 代码页,Windows 1251,并不需要 BOM。 - David Heffernan
@David:我已经用我的示例代码编辑了原始帖子。我怎么知道哪个代码页需要BOM?长度(Preamble)> 0部分是指需要BOM吗? - jonjbar
关于BOM,没有任何8位ANSI代码页(例如您提到的西里尔文)需要BOM。您会在UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BE上看到BOM。甚至在这些编码中也不是所有情况都有BOM - 在Windows上比其他平台更容易看到BOM。 - David Heffernan
简而言之,ANSI文本文件不需要BOM。 - David Heffernan
2个回答

4

不确定您在寻找什么样的示例;也许以下内容可以帮助您 - 此示例将Unicode字符串(SL)转换为ANSI西里尔文:

procedure SaveCyrillic(SL: TStrings; Stream: TStream);
var
  CyrillicEncoding: TEncoding;

begin
  CyrillicEncoding := TEncoding.GetEncoding(1251);
  try
    SL.SaveToStream(Stream, CyrillicEncoding);
  finally
    CyrillicEncoding.Free;
  end;
end;

谢谢,不过使用该方法我必须先将字符串转换为TStrings,这似乎会带来很大的性能损失,这就是为什么我提到了我提取了TStrings.SaveToStream方法。 - jonjbar

2

如果我理解正确,这很简单。声明一个具有Cyrillic 1251亲和性的AnsiString:

type
  // The code page for ANSI-Cyrillic is 1251
  CyrillicString = type AnsiString(1251);

然后将您的Unicode字符串分配给其中之一:

var
  UnicodeText: string;
  CyrillicText: CyrillicString;
....
  CyrillicText := UnicodeText;

您可以按照传统方式将CyrillicText写入流中:

if Length(CyrillicText)>0 then
  Stream.WriteBuffer(CyrillicText[1], Length(CyrillicText));

ANSI编码的文本文件中不应该有BOM。


@menjaraz 不行。你需要使用WideCharToMultiByte - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接