我正在使用Delphi7(非unicode VCL),我需要在TFileStream中存储大量WideStrings.我不能使用TStringStream,因为(宽)字符串与二进制数据混合,格式被预测加速加载和写入数据……但是我相信当前我正在加载/写入字符串的方式可能是我的代码的瓶颈……
目前我正在写一个字符串的长度,然后用char写它char …
在加载时,首先我加载长度,然后通过char加载char …
那么,将WideString保存并加载到TFileStream的最快方法是什么?
提前致谢
解决方法
不是一次读写一个字符,而是一次读取和写入所有字符:
procedure WriteWideString(const ws: WideString; stream: TStream); var nChars: LongInt; begin nChars := Length(ws); stream.WriteBuffer(nChars,SizeOf(nChars); if nChars > 0 then stream.WriteBuffer(ws[1],nChars * SizeOf(ws[1])); end; function ReadWideString(stream: TStream): WideString; var nChars: LongInt; begin stream.ReadBuffer(nChars,SizeOf(nChars)); SetLength(Result,nChars); if nChars > 0 then stream.ReadBuffer(Result[1],nChars * SizeOf(Result[1])); end;
现在,从技术上讲,由于WideString是Windows BSTR,它可以包含奇数个字节. Length函数读取字节数并除以2,因此可能(尽管不太可能)上面的代码将切断最后一个字节.您可以使用此代码:
procedure WriteWideString(const ws: WideString; stream: TStream); var nBytes: LongInt; begin nBytes := SysStringByteLen(Pointer(ws)); stream.WriteBuffer(nBytes,SizeOf(nBytes)); if nBytes > 0 then stream.WriteBuffer(Pointer(ws)^,nBytes); end; function ReadWideString(stream: TStream): WideString; var nBytes: LongInt; buffer: PAnsiChar; begin stream.ReadBuffer(nBytes,SizeOf(nBytes)); if nBytes > 0 then begin GetMem(buffer,nBytes); try stream.ReadBuffer(buffer^,nBytes); Result := SysAllocStringByteLen(buffer,nBytes) finally FreeMem(buffer); end; end else Result := ''; end;
受到Mghie’s answer的启发,用ReadBuffer和WriteBuffer替换了我的Read和Write调用.如果后者无法读取或写入请求的字节数,则会引发异常.