Delphi 读写二进制文件?

Delphi 读写二进制文件?,delphi,delphi-xe,Delphi,Delphi Xe,我正在将一些自定义创建的对象类(流数据)保存到文件中 我需要能够将文件的内容加载到TStringList中,这样我就可以在文件末尾追加一行,然后保存更改 但这不起作用,因为LoadFromFile似乎无法正确解析文件。我假设由于流保存到文件中的有趣字符,TStringList需要简单的文本信息 我怎样才能做到以下几点: 将任何原始二进制文件读入TStringList 添加我的新行,例如StringList1.Add(MyString) 再次保存原始二进制文件 这个问题实际上与我问的另一个问题

我正在将一些自定义创建的对象类(流数据)保存到文件中

我需要能够将文件的内容加载到TStringList中,这样我就可以在文件末尾追加一行,然后保存更改

但这不起作用,因为LoadFromFile似乎无法正确解析文件。我假设由于流保存到文件中的有趣字符,TStringList需要简单的文本信息

我怎样才能做到以下几点:

  • 将任何原始二进制文件读入TStringList
  • 添加我的新行,例如StringList1.Add(MyString)
  • 再次保存原始二进制文件
这个问题实际上与我问的另一个问题有关:

这就是我想做的:

  • 计算我保存的流文件的CRC校验和
  • 将CRC值添加到文件末尾
  • 重新保存文件
然后,当我尝试打开流文件时:

  • 将CRC值(在文件末尾)分配给变量
  • 从文件中删除CRC值
  • 将流文件另存为新的临时文件
  • 计算并比较临时文件的CRC与变量中存储的CRC
  • 如果文件的CRC与内部存储的CRC值匹配,我可以正常处理该文件
但我不知道如何读取或写入文件的原始二进制数据


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

这个类是从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;
类型
TCRCStringList=类(TStringList)
类型
TCRC=长单词;
私有的
函数CalcCRC(Stream:TStream):TCRC;
平民的
过程LoadFromStream(流:TStream;编码:TEncoding);推翻
过程SaveToStream(流:TStream;编码:TEncoding);推翻
终止
函数TCRCStringList.CalcCRC(Stream:TStream):TCRC;
开始
结果:=42;//将CRC计算放在这里
终止
过程TCRCStringList.LoadFromStream(流:TStream;编码:TEncoding);
变量
crc:TCRC;
temp:TMemoryStream;
开始
temp:=TMemoryStream.Create;
尝试
临时复制源(流,流大小-大小(crc));
Stream.Read(crc,Sizeof(crc));
如果crc CalcCRC(温度),则
引发异常。创建('CRC错误');
温度位置:=0;
继承的LoadFromStream(临时、编码);
最后
无温度;
终止
终止
过程TCRCStringList.SaveToStream(流:TStream;编码:TEncoding);
变量
crc:TCRC;
temp:TMemoryStream;
开始
temp:=TMemoryStream.Create;
尝试
继承的SaveToStream(临时、编码);
温度位置:=0;
crc:=CalcCRC(温度);
温度位置:=温度尺寸;
临时写入(crc,Sizeof(crc));
Stream.CopyFrom(临时,0);//count=0从开始复制整个流
最后
无温度;
终止
终止

该类从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;
类型
TCRCStringList=类(TStringList)
类型
TCRC=长单词;
私有的
函数CalcCRC(Stream:TStream):TCRC;
平民的
过程LoadFromStream(流:TStream;编码:TEncoding);推翻
过程SaveToStream(流:TStream;编码:TEncoding);推翻
终止
函数TCRCStringList.CalcCRC(Stream:TStream):TCRC;
开始
结果:=42;//将CRC计算放在这里
终止
过程TCRCStringList.LoadFromStream(流:TStream;编码:TEncoding);
变量
crc:TCRC;
temp:TMemoryStream;
开始
temp:=TMemoryStream.Create;
尝试
临时复制源(流,流大小-大小(crc));
Stream.Read(crc,Sizeof(crc));
如果crc CalcCRC(温度),则
引发异常。创建('CRC错误');
温度位置:=0;
继承的LoadFromStream(临时、编码);
最后
无温度;
终止
终止
过程TCRCStringList.SaveToStream(流:TStream;编码:TEncoding);
变量
crc:TCRC;
temp:TMemoryStream;
开始
temp:=TMemoryStream.Create;
尝试
继承的SaveToStream(临时、编码);
温度位置:=0;
crc:=CalcCRC(温度);
温度位置:=温度尺寸;
临时写入(crc,Sizeof(crc));
Stream.CopyFrom(临时,0);//count=0从开始复制整个流
最后
无温度;
终止
终止

是否将校验和保存到文本文件中?对吗?我仍然不明白你为什么需要校验和。保存到流文件,我这样做是为了每当从我的应用程序打开一个文件时,我都可以确定该文件是否最初是从我的程序保存的。你使用的是什么版本的Delphi?这对Unicode字符串尤其重要(无论是否),最好检测损坏的文件并报告错误。如果用户把文件弄乱了,那就是他们的问题。把它存储在他们的用户档案下,他们就没有理由乱搞它了;免费小费;二进制文件很麻烦。如果您不需要定制二进制文件格式,那么就不需要了。文本文件更加“坚固可靠”,并且在格式错误时更容易进行故障排除。是否将校验和保存到文本文件中?对吗?我仍然不明白你为什么需要校验和。保存到流文件,我这样做是为了每当从我的应用程序打开一个文件时,我都可以确定该文件是否最初是从我的程序保存的。你使用的是什么版本的Delphi?这对Unicode字符串尤其重要(无论是否),最好检测损坏的文件并报告错误。如果用户把文件弄乱了,那就是他们的问题。把它存储在他们的用户档案下,他们就没有理由乱搞它了;免费小费;二进制文件很麻烦。如果您不需要定制二进制文件格式,那么就不需要了。文本文件更加“坚固可靠”,并且在出现马尔福时更容易排除故障