Delphi 是否可以使用字符串数据类型结构写入/读取文件?
例如,对于在文件中写入内容,我使用以下代码:Delphi 是否可以使用字符串数据类型结构写入/读取文件?,delphi,file,delphi-xe2,Delphi,File,Delphi Xe2,例如,对于在文件中写入内容,我使用以下代码: procedure MyProc (... ); const BufSize = 65535; var FileSrc, FileDst: TFileStream; StreamRead: Cardinal; InBuf, OutBuf: Array [0..bufsize] of byte; begin ..... FileSrc := TFileStream.Create (uFileSrc, fmOpenRead Or
procedure MyProc (... );
const
BufSize = 65535;
var
FileSrc, FileDst: TFileStream;
StreamRead: Cardinal;
InBuf, OutBuf: Array [0..bufsize] of byte;
begin
.....
FileSrc := TFileStream.Create (uFileSrc, fmOpenRead Or fmShareDenyWrite);
try
FileDst := TFileStream.Create (uFileTmp, fmCreate);
try
StreamRead := 0;
while ((iCounter < iFileSize) or (StreamRead = Cardinal(BufSize)))
begin
StreamRead := FileSrc.Read (InBuf, BufSize);
Inc (iCounter, StreamRead);
end;
finally
FileDst.Free;
end;
finally
FileSrc.Free;
end;
end;
那就不行了。从某种意义上说,该文件不会什么都不写。我已经理解了原因,或者只是想理解它。
我认为问题可能在于为什么字符串只包含指向内存的指针,而不是静态结构;对的
在这种情况下,有什么解决办法吗?从某种意义上说,我可以用字符串而不是向量来写一个文件吗?或者我需要一个向量?
如果可能的话,我能做什么?
非常感谢。是的,您可以在流中保存/加载字符串,请参见以下示例
var Len: Integer;
buf: string;
FData: TStream;
// save string to stream
// save the length of the string
Len := Length(buf);
FData.Write(Len, SizeOf(Len));
// save string itself
if(Len > 0)then FData.Write(buf[1], Len * sizeof(buf[1]));
// read string from stream
// read the length of the string
FData.Read(Len, SizeOf(Len));
if(Len > 0)then begin
// get memory for the string
SetLength(buf, Len);
// read string content
FData.Read(buf[1], Len * sizeof(buf[1]));
end else buf := '';
是的,您可以在流中保存/加载字符串,请参见以下示例
var Len: Integer;
buf: string;
FData: TStream;
// save string to stream
// save the length of the string
Len := Length(buf);
FData.Write(Len, SizeOf(Len));
// save string itself
if(Len > 0)then FData.Write(buf[1], Len * sizeof(buf[1]));
// read string from stream
// read the length of the string
FData.Read(Len, SizeOf(Len));
if(Len > 0)then begin
// get memory for the string
SetLength(buf, Len);
// read string content
FData.Read(buf[1], Len * sizeof(buf[1]));
end else buf := '';
使用字符串有两个问题。首先,您希望使用
RawByteString
,以确保使用字节大小的字符元素–Unicode字符串包含两个字节宽的元素。其次,你需要取消对字符串的引用,它实际上只是一个指针
但我想知道为什么您更喜欢字符串而不是堆栈分配的字节数组
procedure MyProc (... );
const
BufSize = 65536;
var
FileSrc, FileDst: TFileStream;
StreamRead: Cardinal;
InBuf: RawByteString;
begin
.....
FileSrc := TFileStream.Create (uFileSrc, fmOpenRead Or fmShareDenyWrite);
try
FileDst := TFileStream.Create (uFileTmp, fmCreate);
try
SetLength(InBuf, BufSize);
StreamRead := 0;
while ((iCounter < iFileSize) or (StreamRead = Cardinal(BufSize)))
begin
StreamRead := FileSrc.Read (InBuf[1], BufSize);
Inc (iCounter, StreamRead);
end;
finally
FileDst.Free;
end;
finally
FileSrc.Free;
end;
end;
程序MyProc(…);
常数
BufSize=65536;
变量
FileSrc,FileDst:TFileStream;
StreamRead:红衣主教;
InBuf:RawByteString;
开始
.....
FileSrc:=TFileStream.Create(uFileSrc、fmOpenRead或fmShareDenyWrite);
尝试
FileDst:=TFileStream.Create(uFileTmp,fmCreate);
尝试
设置长度(InBuf,BufSize);
StreamRead:=0;
而((iCounter
注意:您以前的代码声明了一个65536字节的缓冲区,但您只使用了其中的65535字节。可能不是您想要的。使用字符串有两个问题。首先,您希望使用
RawByteString
,以确保使用字节大小的字符元素–Unicode字符串包含两个字节宽的元素。其次,你需要取消对字符串的引用,它实际上只是一个指针
但我想知道为什么您更喜欢字符串而不是堆栈分配的字节数组
procedure MyProc (... );
const
BufSize = 65536;
var
FileSrc, FileDst: TFileStream;
StreamRead: Cardinal;
InBuf: RawByteString;
begin
.....
FileSrc := TFileStream.Create (uFileSrc, fmOpenRead Or fmShareDenyWrite);
try
FileDst := TFileStream.Create (uFileTmp, fmCreate);
try
SetLength(InBuf, BufSize);
StreamRead := 0;
while ((iCounter < iFileSize) or (StreamRead = Cardinal(BufSize)))
begin
StreamRead := FileSrc.Read (InBuf[1], BufSize);
Inc (iCounter, StreamRead);
end;
finally
FileDst.Free;
end;
finally
FileSrc.Free;
end;
end;
程序MyProc(…);
常数
BufSize=65536;
变量
FileSrc,FileDst:TFileStream;
StreamRead:红衣主教;
InBuf:RawByteString;
开始
.....
FileSrc:=TFileStream.Create(uFileSrc、fmOpenRead或fmShareDenyWrite);
尝试
FileDst:=TFileStream.Create(uFileTmp,fmCreate);
尝试
设置长度(InBuf,BufSize);
StreamRead:=0;
而((iCounter
注意:您以前的代码声明了一个65536字节的缓冲区,但您只使用了其中的65535字节。可能不是您想要的。要使用字符串作为缓冲区(我不建议这样做),您必须使用SetLength来分配内部缓冲区,并且必须将InBuf[1]和extuf[1]作为要读取或写入的数据传递
var
InBuf, OutBuf: AnsiString; // or TBytes
begin
SetLength(InBuf, BufSize);
SetLength(OutBuf, BufSize);
...
StreamRead := FileSrc.Read(InBuf[1], BufSize); // if TBytes, use InBuf[0]
// etc...
您也可以使用TBytes,而不是AnsiString。用法保持不变
但实际上,我认为在这里动态分配tbyte、ansistring或rawbytestring没有任何优势。我宁愿做您已经做过的事情:使用基于堆栈的缓冲区。在多线程环境中,我可能会将其缩小一点。要使用字符串作为缓冲区(我不建议这样做),您必须使用SetLength来分配内部缓冲区,并且必须将InBuf[1]和extuf[1]作为数据传递给读写
var
InBuf, OutBuf: AnsiString; // or TBytes
begin
SetLength(InBuf, BufSize);
SetLength(OutBuf, BufSize);
...
StreamRead := FileSrc.Read(InBuf[1], BufSize); // if TBytes, use InBuf[0]
// etc...
您也可以使用TBytes,而不是AnsiString。用法保持不变
但实际上,我认为在这里动态分配tbyte、ansistring或rawbytestring没有任何优势。我宁愿做您已经做过的事情:使用基于堆栈的缓冲区。在多线程环境中,我可能会将其缩小一点。在相关说明中,要将内容从一个
TStream
复制到另一个TStream
,您只需使用TStream.CopyFrom()
方法即可:
procedure MyProc (... );
var
FileSrc, FileDst: TFileStream;
begin
...
FileSrc := TFileStream.Create (uFileSrc, fmOpenRead Or fmShareDenyWrite);
try
FileDst := TFileStream.Create (uFileTmp, fmCreate);
try
FileDst.CopyFrom(FileSrc, 0); // or FileDst.CopyFrom(FileSrc, iFileSize)
finally
FileDst.Free;
end;
finally
FileSrc.Free;
end;
...
end;
可以通过调用CopyFile()来简化:
无论哪种方式,您都不必担心手动读取/写入文件数据 在相关说明中,要将内容从一个
TStream
复制到另一个TStream
,您只需使用TStream.CopyFrom()
方法即可:
procedure MyProc (... );
var
FileSrc, FileDst: TFileStream;
begin
...
FileSrc := TFileStream.Create (uFileSrc, fmOpenRead Or fmShareDenyWrite);
try
FileDst := TFileStream.Create (uFileTmp, fmCreate);
try
FileDst.CopyFrom(FileSrc, 0); // or FileDst.CopyFrom(FileSrc, iFileSize)
finally
FileDst.Free;
end;
finally
FileSrc.Free;
end;
...
end;
可以通过调用CopyFile()来简化:
无论哪种方式,您都不必担心手动读取/写入文件数据 为什么使用字符串?堆栈分配的字节缓冲区在我看来很好;因为数据都是字符串unicode,所以我需要对它进行操作。只是为了不做太多从字符串unicode到字节数组的转换,并对代码进行semplify。另一个原因是我希望在类中使用“bufsize”变量而不是静态变量。当我使用动态数组并设置它的长度时,我也有同样的问题。到底是什么问题?我假设您不只是将数据从一个文件复制到另一个文件,对吗?在你再次写出数据之前,你需要做一些处理,对吗?嗯,帕斯卡的匈牙利符号系统。。。逐字符读取字符串,遇到#0时停止读取为什么使用字符串?堆栈分配的字节缓冲区在我看来很好;因为数据都是字符串unicode,所以我需要对它进行操作。只是为了不做太多从字符串unicode到字节数组的转换,并对代码进行semplify。另一个原因是我希望在类中使用“bufsize”变量而不是静态变量。当我使用动态数组并设置它的长度时,我也有同样的问题。什么