读写二进制文件?

时间:2011-12-23 15:32:25

标签: delphi delphi-xe

我将一些自定义创建的Objects类(Stream数据)保存到File。

我需要能够将File的内容加载到TStringList中,这样我就可以在File的末尾添加一个新行,然后保存更改。

这不起作用,因为LoadFromFile似乎无法正确解析文件。我假设因为Stream保存为文件的有趣字符,而TStringList需要纯文本信息。

如何执行以下操作:

  • 将任何原始二进制文件读入TStringList。
  • 添加我的新行,例如StringList1.Add(MyString);
  • 再次保存原始二进制文件。

这个问题实际上与我提出的另一个问题有关:Save a CRC value in a file, without altering the actual CRC Checksum?

这就是我想要做的事情:

  • 计算我保存的流文件的CRC校验和。
  • 将CRC值添加到文件的末尾。
  • 重新保存文件。

然后当我尝试打开我的流文件时:

  • 将CRC值(在文件末尾)分配给变量。
  • 从文件中删除CRC值。
  • 将流文件另存为新的临时文件。
  • 计算并比较Temp文件的CRC,以及存储在变量中的CRC。
  • 如果文件的CRC与内部存储的CRC值匹配,我可以正常处理文件。

但我不知道如何读取或写入文件的原始二进制数据。

如果有人能给我一些帮助和建议,我将不胜感激:)

1 个答案:

答案 0 :(得分:5)

此类从TStringList继承,并在写入文件时在末尾添加检查值。无论何时读取文件,都会检查此值。

type
  TCRCStringList = class(TStringList)
  type
    TCRC = LongWord;
  private
    function CalcCRC(Stream: TStream): TCRC;
  public
    procedure LoadFromStream(Stream: TStream; Encoding: TEncoding); override;
    procedure SaveToStream(Stream: TStream; Encoding: TEncoding); override;
  end;

function TCRCStringList.CalcCRC(Stream: TStream): TCRC;
begin
  Result := 42;  // place CRC calculation here
end;

procedure TCRCStringList.LoadFromStream(Stream: TStream; Encoding: TEncoding);
var
  crc: TCRC;
  temp: TMemoryStream;
begin
  temp := TMemoryStream.Create;
  try
    temp.CopyFrom(Stream, Stream.Size - Sizeof(crc));
    Stream.Read(crc, Sizeof(crc));
    if crc <> CalcCRC(temp) then
      raise Exception.Create('CRC error');
    temp.Position := 0;
    inherited LoadFromStream(temp, Encoding);
  finally
    temp.Free;
  end;
end;

procedure TCRCStringList.SaveToStream(Stream: TStream; Encoding: TEncoding);
var
  crc: TCRC;
  temp: TMemoryStream;
begin
  temp := TMemoryStream.Create;
  try
    inherited SaveToStream(temp, Encoding);
    temp.Position := 0;
    crc := CalcCRC(temp);
    temp.Position := temp.Size;
    temp.Write(crc, Sizeof(crc));
    Stream.CopyFrom(temp, 0); // count = 0 copies the whole stream from the beginning
  finally
    temp.Free;
  end;
end;