delphi - 记录文件升级和向后兼容性

标签 delphi record backwards-compatibility delphi-5

我有这样的文件:

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));

最佳答案

老式的 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'

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

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

关于delphi - 记录文件升级和向后兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14886301/

相关文章:

delphi - 暂时禁用 Delphi 中 TvertScrollBox 组件的滚动?

windows - 通过 API Windows Firewall Delphi 添加规则阻止 IP 地址

haskell - 在类和记录之间进行选择

c++ - 静态编译会破坏ABI吗?

delphi - 自定义组件创建 - 如何在工具面板中添加表示组件的小图标?

list - 在 f# 中处理列表的嵌套记录

mysql - MYSQL 多数据到一条记录

c++ - 针对 Visual Studio 2008 的 C++11 代码的兼容性

c# - 当外部库不向后兼容时检查属性是否存在

delphi - 虚拟字符串树中节点/行中的多个复选框/单选按钮