0

我正在将字符串写入文件并使用 binarywriter 和 binaryreader 将其读回。当字符串被读回时,它看起来很有趣而且很长。我不知道它为什么这样做。

这是我使用 binarywriter 写入文件的方法:

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”而不是包含垃圾的长字符串。

那么,我做错了什么?这是字符串格式错误吗?

4

1 回答 1

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;
于 2013-04-03T19:31:16.440 回答