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バイトにアラインされたときに未使用のバイトが1バイトでした。

質問:この新しいファイルが古いコードから読み取られると、どうなりましたか?彼は後方互換性が必要です。

古いコード読み取りサンプル:

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

古い学校の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 に答える