TStreamWriter = class(TTextWriter)
public
// 有4个构造函数(可以传文件流、内存流,也可是文件名)
constructor Create(Stream: TStream); overload;
constructor Create(Stream: TStream; Encoding: TEncoding; BufferSize: Integer = 4096); overload;
constructor Create(const Filename: string; Append: Boolean = False); overload;
constructor Create(const Filename: string; Append: Boolean; Encoding: TEncoding; BufferSize: Integer = 4096); overload;
...
end;
使用起来非常方便,比如实例sw.WriteLine('xxx');即可以输出到内存也可以输出到文件
缓冲区设置问题:当要写的文件数据较大时,BufferSize可以设大点,另外一定要将AutoFlush := False;不然的话每执行一次Write操作就会写盘,能慢死。
UTF8 with BOM问题:看源码发现执行Create(Stream: TStream);构造函数时不写BOM头,但也没法设置BufferSize了
constructor TStreamWriter.Create(Stream: TStream; Encoding: TEncoding; BufferSize: Integer);
begin
inherited Create;
FOwnsStream := False;
FStream := Stream;
FEncoding := Encoding;
if BufferSize >= 128 then
SetLength(FBuffer, BufferSize)
else
SetLength(FBuffer, 128);
FBufferIndex := 0;
FNewLine := sLineBreak;
FAutoFlush := True;
// 注意这一段,就是写BOM头的
if Stream.Position = 0 then
WriteBytes(FEncoding.GetPreamble);
end;
如果需要同时设置BufferSize还不想要BOM怎么办?
简单,TStreamWriter有个属性叫BastStream
property BaseStream: TStream read FStream;
不管是外面传进去的Stream还是本身根据文件名创建的,都是它
// 写了BOM头后Position和Size应该是3了,把Size清零
sw.BaseStream.Size := 0;