BOM必須來自源TStream
,因爲TStringStream
不寫入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;
我沒有看到有什麼*錯*。 'TStream.CopyFrom'只是簡單地複製所有被告知的數據。 –
@RobKennedy你說得對,但我希望DataString函數可以返回沒有BOM的字符串。我稍微改變了問題標題。 –
僅供參考,如果第二個參數爲0,則CopyFrom()將流的Position重置爲0,並讀取整個流。如果Position位於流的末尾,那麼最終可能會返回您不期望的內容。 –