Effectively using Delphi to read blocks of unknown size from a file

In the past, I saw this work, but I never understood how it should be done.
Suppose we have a file of known data types , but an unknown length , like a dynamic array TSomething, where

type
  TSomething = class
    Name: String;
    Var1: Integer;
    Var2: boolean;
  end;

The problem is that this type of object can be expanded in the future by adding more variables (e.g. Var3: String).
Then, files saved with an older version will not contain the latest variables .
The file reading procedure must somehow recognize the data in blocks using an algorithm such as:

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;

BlockRead BlockWrite, , , , , ( ), , .

, :
SO - Delphi 2010: ?
Delphi - BlockRead
SO - / - Delphi
SO - FileStream Delphi?

+4
4

, . , , , , , .

, . Min(ElementLength, YourRecordSize) .

, . . , - , .

(, 1970- ) , , - , . . . JSON, XML, YAML .

+7

, . , , . , , , , .

+5

, TSomething. , , .

Sqlite, , , .

, . , . , , , .

/ /XML/JSON ( ) blockread/blockwrite, .

, , ( ). , , TSomething , , , , .

+1

: . , .

( ):

Procedure Read (MyFile : TFile);
Var
  reader : IMyFileReader;

begin
  versionInfo = MyFile.ReadVersionInfo();
  reader = ReaderFactory.CreateFromVersion(versionInfo);
  reader.Read(MyFile);
end;


Type
  ReaderFactory = Class
  public 
    class function CreateFromVersion(VersionInfo : TVersionInfo) : IMyFileReader;
  end;

function ReaderFactory.CreateFromVersion(VersionInfo : TVersionInfo) : IMyFileReader;
begin
  if VersionInfo = '0.9-Alpha' then
    result := TVersion_0_9_Alpha_Reader.Create()
  else if VersionInfo = '1.0' then
    result := TVersion1_0_Reader.Create()
  else ....
end;

It can be easily maintained and expanded forever. You will never have to touch the reader, but add a new reader and improve the factory. Using a simple registration method and TDictionary<TVersionInfo,TMyFileReaderClass>you can even not change the factory.

+1
source

All Articles