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;
Кажется, что файл прекрасно сохраняется, когда я открываю его с помощью шестнадцатеричного редактора, я могу найти правильные строки, сохраненные там, но загрузка выдает ошибки.
Не могли бы вы помочь мне?
1 ответ
Вы сохраняете количество байтов, и именно столько байтов вы пишете. Когда вы читаете значение, вы рассматриваете его как количество символов, а затем читаете столько байтов. Это не вызовет проблемы, с которой вы столкнулись сейчас, поскольку вы делаете буфер больше, чем нужно на Delphi 2009.
Проблема в том, что вы читаете строковую переменную, а не ее содержимое. Ты использовал str[1]
при написании; сделать то же самое при чтении. В противном случае вы перезаписываете строковую ссылку, выделенную при вызове. SetLength
,
Read(nBytes, SizeOf(Integer));
nChars := nBytes div SieOf(Char);
SetLength(str, nChars);
Read(str[1], nBytes);
И да, вам нужно позвонить SetLength
, Read
Он не знает, во что он читает, поэтому он не может знать, что ему нужно заранее установить размер.