我正在将一个字符串写入文件并使用binarywriter和binaryreader将其读回。当字符串被读回时,它看起来很有趣而且很长。我不知道为什么这样做。
以下是我使用二进制文件写入文件的方式:
TFileHeader = Record
ID:String;
version:SmallInt;
end;
method WriteGroups(fname:string; cg:ArrayList);
var
strm : BinaryWriter;
i:integer;
cnt:Integer;
GroupHeader:TFileHeader;
begin
GroupHeader.ID:='GroupFile'; <<<-----I am having problem with this string.
GroupHeader.version:=6;
if Environment.OSVersion.Platform = System.PlatformID.Unix then
fname := baseDir +'/calgroup.dat'
else
fname := baseDir +'\calgroup.dat';
if cg.Count > 0 then
begin
strm := new BinaryWriter(File.Create(fname));
cnt := cg.Count;
strm.Write(GroupHeader.version);
strm.Write(GroupHeader.ID);
strm.Write(cnt);
for i := 0 to cnt - 1 do
begin
TCalGroup(cg[i]).WriteMGroup(strm);
end;
strm.Close;
end;
end;
以下是我使用BinaryReader从文件中读取的内容:
method ReadGroups(fname:string; cg:ArrayList);
var
strm : BinaryReader;
GroupHeader:TFileHeader;
cnt:SmallInt;
i:integer;
cgp:TMagiKalCalGroup;
begin
GroupHeader.ID :='';
GroupHeader.version := 0;
if Environment.OSVersion.Platform = System.PlatformID.Unix then
fname := baseDir +'/calgroup.dat'
else
fname := baseDir +'\calgroup.dat';
if File.Exists(fname) then
begin
ClearGroups(cg);
strm := new BinaryReader(file.OpenRead(fname));
GroupHeader.version:=strm.ReadInt32;
GroupHeader.ID := strm.ReadString; <-----Here is the problem. See the image below..
if ((GroupHeader.ID='') or (GroupHeader.version>100)) then
begin
strm.Close;
Exit;
end;
if (GroupHeader.version<5) then
begin
strm.Close;
exit;
end;
cnt := strm.ReadInt16;
for i := 0 to cnt - 1 do
begin
reformat:=false;
cgp := new TMagiKalCalGroup('New Grp');
cgp.ReadMGroup(Strm);
cgp.UpdateDateTime(System.DateTime.Now);
cg.Add(cgp);
end;
//strm.Free;
strm.Close;
end;
end;
这是我在调试代码时看到的内容:
正如您可以看到或未看到的那样,“GroupHeader.ID”应该只包含“Groupfile”而不是带有垃圾的长字符串。
那么,我做错了什么?这是字符串格式错误吗?
答案 0 :(得分:2)
Smallint
是一个16位值。在读取文件时,您将该值读取为32位值而不是16位值,因此您最终会读取属于存储字符串长度的一些字节。然后当你读取字符串时,字符串字符的前2个字节被解释为字符串长度的一部分,这就是你最终垃圾的原因。
阅读群组时,您会遇到类似的逻辑错误。 Integer
是32位值。当读取组计数时,您将其读取为16位值,这意味着您的组读取将被关闭2个字节并且也将被损坏。
您需要更改ReadGroups()
功能内的这些行:
cnt: Smallint;
...
GroupHeader.version:=strm.ReadInt32;
...
cnt := strm.ReadInt16;
改为:
cnt: Integer;
...
GroupHeader.version := strm.ReadInt16;
...
cnt := strm.ReadInt32;