gpt4 book ai didi

delphi - 为什么TStringStream转换为字符串时不去掉BOM?

转载 作者:行者123 更新时间:2023-12-03 15:39:54 27 4
gpt4 key购买 nike

我们有一个像这样的库函数:

class function TFileUtils.ReadTextStream(const AStream: TStream): string;
var
StringStream: TStringStream;
begin
StringStream := TStringStream.Create('', TEncoding.Unicode);
try
// This is WRONG since CopyFrom might rewind the stream (see Remys comment)
StringStream.CopyFrom(AStream, AStream.Size - AStream.Position);
Result := StringStream.DataString;
finally
StringStream.Free;
end;
end;

当我检查函数返回的字符串时,第一个 Char 是(小端)BOM。

为什么 TStringStream 不忽略 BOM?

有更好的方法吗?我不需要向后兼容旧的 Delphi 版本,XE2 的工作解决方案就可以了。

最佳答案

BOM 必须来自源 TStream,因为 TStringStream 不写入 BOM。如果您想忽略源中存在的 BOM,则必须在复制数据之前手动执行此操作,例如:

class function TFileUtils.ReadTextStream(const AStream: TStream): string;
var
StreamPos, StreamSize: Int64;
Buf: TBytes;
NumBytes: Integer;
Encoding: TEncoding;
begin
Result := '';

StreamPos := AStream.Position;
StreamSize := AStream.Size - StreamPos;

// Anything available to read?
if StreamSize < 1 then Exit;

// Read the first few bytes from the stream...
SetLength(Buf, 4);
NumBytes := AStream.Read(Buf[0], Length(Buf));
if NumBytes < 1 then Exit;
Inc(StreamPos, NumBytes);
Dec(StreamSize, NumBytes);

// Detect the BOM. If you know for a fact what the TStream data is encoded as,
// you can assign the Encoding variable to the appropriate TEncoding object and
// GetBufferEncoding() will check for that encoding's BOM only...
SetLength(Buf, NumBytes);
Encoding := nil;
Dec(NumBytes, TEncoding.GetBufferEncoding(Buf, Encoding));

// If any non-BOM bytes were read than rewind the stream back to that position...
if NumBytes > 0 then
begin
AStream.Seek(-NumBytes, soCurrent);
Dec(StreamPos, NumBytes);
Inc(StreamSize, NumBytes);
end else
begin
// Anything left to read after the BOM?
if StreamSize < 1 then Exit;
end;

// Now read and decode whatever is left in the stream...
StringStream := TStringStream.Create('', Encoding);
try
StringStream.CopyFrom(AStream, StreamSize);
Result := StringStream.DataString;
finally
StringStream.Free;
end;
end;

关于delphi - 为什么TStringStream转换为字符串时不去掉BOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14264554/

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