2

TFileStreamを使用して、固定されていない文字列を読み書きしようとしています。ただし、アクセス違反エラーが発生します。これが私のコードです:

// Saving a file
  (...)
  count:=p.Tags.Count; // Number of lines to save (Tags is a TStringList)
  FS.Write(count, SizeOf(integer));
  for j := 0 to p.Tags.Count-1 do
  begin
    str:=p.Tags.Strings[j];
    tmp:=Length(str)*SizeOf(char);
    FS.Write(tmp, SizeOf(Integer));
    FS.Write(str[1], Length(str)*SizeOf(char));
  end;

// Loading a file
  (...)
  p.Tags.Add('hoho'); // Check if Tags is created. This doesn't throw an error.
  Read(TagsCount, SizeOf(integer)); // Number of lines to read
  for j := 0 to TagsCount-1 do
  begin
    Read(len, SizeOf(Integer)); // length of this line of text
    SetLength(str, len); // don't know if I have to do this
    Read(str, len); // No error, but str has "inaccessible value" in watch list
    p.Tags.Add(str); // Throws error
  end;

ファイルは問題なく保存されているようです。16進エディタでファイルを開くと、そこに保存されている正しい文字列を見つけることができますが、読み込み中にエラーが発生します。

手伝ってくれませんか。

4

1 に答える 1

8

あなたはバイト数を節約します、そしてそれはあなたが書くバイト数です。値を読み取るときは、それを文字数として扱い、その数のバイトを読み取ります。ただし、 Delphi 2009の時点で必要以上にバッファを大きくしているため、現在発生している問題は発生しません。

問題は、文字列の内容ではなく、文字列変数を読み込んでいることです。あなたはstr[1]書くときに使用しました。読むときも同じようにします。そうしないと、を呼び出したときに割り当てた文字列参照が上書きされますSetLength

Read(nBytes, SizeOf(Integer));
nChars := nBytes div SieOf(Char);
SetLength(str, nChars);
Read(str[1], nBytes);

そして、はい、あなた呼び出す必要がありますSetLengthReadは何を読み込んでいるかわからないため、事前にサイズを設定する必要があることを知る方法がありません。

于 2012-07-16T14:53:50.453 に答える