3

我有这样的文件:

file of record
  Str: string[250];
  RecType: Cardinal;
end;

但在使用此文件一段时间后,我的客户发现,Str 永远不会大于 100 个字符,而且他还需要额外的字段。

在新版本中,我们有这样的文件:

file of packed record
  Str: string[200];
  Reserved: array[1..47] of Byte;
  NewFiled: Cardinal;
  RecType: Cardinal;
end;

这条记录的大小相同,在之前的记录中,Str 和 RecType 之间的记录在对齐到 8 个字节时是一个未使用的字节。

问题:发生了什么,当这个新文件将从旧代码中读取时?他需要向后兼容。

旧代码阅读示例:

var
  FS: TFileStream;
  Rec: record
         Str: string[250];
         RecType: Cardinal;
       end;
...
// reading record by record from file:
FS.Read(Rec, SizeOf(Rec));
4

1 回答 1

3

old school pascal 字符串使用字符串的第一个字节(索引 0)来存储字符串的长度。

我们来看看这条记录的内存:

byte    0  1  2  3  4  5  6  7  8  9 10 11  12  13 ........ 243..246 247..250
value  10 65 66 67 68 69 70 71 72 73 74  0 200 130          NewField RecType

从字节 11 到 242,内存可以包含垃圾,它会被程序简单地忽略(从未显示),因为这将字节 0 处的值 10 作为字符串的长度,因此字符串变为'ABCDEFGHIJ'

这确保了读取使用最新版本创建的文件的旧程序永远不会在字符串末尾看到垃圾,因为字符串的视图将被限制为字符串的实际大小,并且内存位置将被忽略。

您必须仔细检查旧程序是否不会更改存储的值,以防将记录写回文件。我认为它也是安全的,但我只是不确定并且手头没有 Delphi 可以测试。

于 2013-02-15T01:07:39.267 回答