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;

Файл, кажется, сохраняется просто отлично, когда я открываю его с помощью шестнадцатеричного редактора, я могу найти сохраненные там правильные строки, но загрузка выдает ошибки.

Вы не могли бы мне помочь?


person Martin Melka    schedule 16.07.2012    source источник


Ответы (1)


Вы сохраняете количество байтов, и именно столько байтов вы записываете. Когда вы читаете значение, вы считаете его числом символов, а затем читаете столько же байтов. Однако это не вызовет проблемы, которую вы видите сейчас, поскольку вы делаете буфер больше, чем он должен быть в Delphi 2009.

Проблема в том, что вы читаете строковую переменную, а не содержимое строки. Вы использовали str[1] при написании; делать то же самое при чтении. В противном случае вы перезаписываете ссылку на строку, которую вы выделили при вызове SetLength.

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

И да, вам нужно позвонить SetLength. Read не знает, во что он считывается, поэтому он не может знать, что ему нужно заранее установить размер.

person Rob Kennedy    schedule 16.07.2012