繁体   English   中英

加载记录的不同版本

[英]Loading different versions of the record

我在磁盘上的记录中有几个版本的数据:

TRec_v1 = record
  Type: UInt32;
  DT1: TDateTime;
end;

TRec_v2 = record
  Type: UInt32;
  DT1: TDateTime;
  DT2: TDateTime;
end;

TRec_v3 = record
  Type: UInt32;
  DT1: TDateTime;
  DT2: TDateTime;
  DT3: TDateTime;
end;

哪种禁食方法可以阅读?

目前,我使用这种方法:

  var
    Rec: TRec_v3;
    Rec1: TRec_v1;
    Rec2: TRec_v2;

  FStream := TFileStream.Create(RecPath, fmOpenRead);
  try
    if FStream.Size = SizeOf(TRec_v1) then
      // read to Rec1, assignt to Rec
    else
    if FStream.Size = SizeOf(TRec_v2) then
      // read to Rec2, assigne to Rec
    else
    if FStream.Size = SizeOf(TRec_v3) then
      // read to Rec
  finally
    FStream.Free;
  end;

注意:每个较新的版本都包含以前版本的所有字段+新字段

如果文件中仅存储一条记录,则可以使用case语句代替一系列的if语句。 并且由于您的新记录包含与旧记录相同的字段,因此您也不需要单独的变量:

var
  Rec: TRec_v3;
  RecSize: Integer;

FStream := TFileStream.Create(RecPath, fmOpenRead);
try
  RecSize := FStream.Size;
  case RecSize of
    SizeOf(TRec_v1),
    SizeOf(TRec_v2),
    SizeOf(TRec_v3):
    begin
      FStream.ReadBuffer(Rec, RecSize);
    end;
  else
    raise Exception.Create('Unsupported record size detected');
  end;
finally
  FStream.Free;
end; 

// use Rec fields depending on RecSize...

或者:

type
  TRec_v1 = record
    Type: UInt32;
    DT1: TDateTime;
  end;

  TRec_v2 = record
    Type: UInt32;
    DT1: TDateTime;
    DT2: TDateTime;
  end;

  TRec_v3 = record
    Type: UInt32;
    DT1: TDateTime;
    DT2: TDateTime;
    DT3: TDateTime;
  end;

  TRec = record
    case Integer of
      0: (v1: TRec_v1);
      1: (v2: TRec_v2);
      2: (v3: TRec_v3);
  end;

var
  Rec: TRec;
  RecSize: Integer;

FStream := TFileStream.Create(RecPath, fmOpenRead);
try
  RecSize := FStream.Size;
  case RecSize of
    SizeOf(TRec_v1),
    SizeOf(TRec_v2),
    SizeOf(TRec_v3):
    begin
      FStream.ReadBuffer(Rec, RecSize);
    end;
  else
    raise Exception.Create('Unsupported record size detected');
  end;
finally
  FStream.Free;
end; 

// use Rec.v1, Rec.v2, or Rec.v3 depending on RecSize...

哪个是最快的阅读方法?

读取记录的代码性能将完全由文件访问控制。 如问题所述,大部分时间都花在打开文件上。

使用case语句或if语句只是一个优先事项,不会导致明显的性能变化。

如果将这些代码埋在一个更大的整体中,那么我认为没有人能在看不到更大代码的情况下就性能提出建议。

给定问题中的代码,以可衡量的方式提高性能的唯一范围是仅一次而不是多次评估流大小。

var
  Size: Int64;
....
Size := Stream.Size;
// test Size

即使在这里,我也怀疑您会看到明显的性能影响。 但是,通常最好不要重复自己的操作,并且此更改会导致代码分解更好。

您必须评估性能以评估建议的优化。

最后,您的整个方法都很脆弱。 如果在v3结构中添加整数,则记录大小将增加8,并且由于对齐而产生填充。 添加另一个整数,大小不变,第二个整数适合填充。 基于类型字段的区分将更加健壮和可扩展。

我建议创建,读取和写入变体记录 ,然后使用标记区分它们:

type recordTypeName = record
  fieldList1: type1;
   ...
  fieldListn: typen;
case tag: ordinalType of
  constantList1: (variant1);
   ...
  constantListn: (variantn);
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM