有效地使用Delphi从文件中读取未知大小的块

mav*_*ros 4 delphi

在过去,我看过这项工作,但我从未真正理解应该如何做.
假设我们有一个已知数据类型文件,但未知长度,如动态数组TSomething,其中

type
  TSomething = class
    Name: String;
    Var1: Integer;
    Var2: boolean;
  end;
Run Code Online (Sandbox Code Playgroud)

但问题是,将来可能会扩展此对象类型,添加更多变量(例如Var3: String).
然后,使用旧版本保存的文件将不包含最新的变量.
文件读取过程应该以某种方式识别中的数据,使用如下算法:

procedure Read(Path: String)
begin
  // Read Array Size
  //   Read TSomething --> where does this record end? May not contain Var3!
  //   --> how to know that the next data block I read is not a new object?
end;
Run Code Online (Sandbox Code Playgroud)

我已经看过这个工作BlockReadBlockWrite,并且我假设每个对象应该在将自己写入文件之前写出它的大小,但我会欣赏一个例子(不一定是代码),知道我正在思考正确的方向.

相关读物我发现:
SO - Delphi 2010:如何将整个记录保存到文件中?
Delphi Basics - BlockRead
SO - 读取/写入文件的动态对象数组 - Delphi
SO - 如何在Delphi中将动态数组保存到FileStream?

Dav*_*nan 7

为了使其工作,您需要将元素大小写入文件.然后,当您阅读该文件时,您将读取该元素长度,该元素长度允许您读取每个元素,即使您的程序不知道如何理解所有元素.

在匹配您的记录与磁盘记录方面,如果您的记录只包含简单类型,那么这很容易.在这种情况下,您可以从文件Min(ElementLength, YourRecordSize)字节读取到您的记录中.

但它看起来并不像你实际拥有那种情况.您的记录实际上是一个类,因此不适合内存复制.更重要的是,它的第一个成员是一个绝对不是简单类型的字符串.

回到当天(比如20世纪70年代),你所描述的技术就是文件的阅读方式.但是现在节目已经开始了.将结构化数据保存到文件通常意味着使用更灵活和适应性更强的序列化格式.您应该考虑使用JSON,XML,YAML或类似的任务.


Pie*_*r B 5

我想你需要一种版本化文件的方法.这样你就知道文件中包含哪个版本的记录.将其写在文件的开头,然后在读取时,首先读入版本标识符,然后使用相应的结构来读取其余部分.