TFileStream并使用String进行操作

时间:2012-07-16 14:49:08

标签: delphi tfilestream

我正在尝试使用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;

该文件似乎保存得很好,当我用hexeditor打开它时,我可以找到保存在那里的正确字符串,但加载会抛出错误。

你可以帮帮我吗?

1 个答案:

答案 0 :(得分:8)

您保存字节的数量,这就是您编写的字节的数量。当您读取该值时,将其视为字符的数量,然后读取许多字节。但是,这不会导致你现在看到的问题,因为你正在使缓冲区更大,而不是像Delphi 2009那样。

问题是你正在读取字符串变量,而不是字符串的内容。你在写作时使用了str[1];阅读时也一样。否则,您将覆盖调用SetLength时分配的字符串引用。

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

是的,你需要致电SetLengthRead不知道它的读数是什么,所以它无法知道它需要事先将大小设置为任何东西。