Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > проблема со Stream


Автор: Burka 9.8.2007, 11:04
Идея такая: записывать в файл через потоки длинну строки, потом сому строку. А читать, соответственно, длинну а потом строку.
но вот этот код не работает, подскажите, где проблема?

Запись
Код

procedure TForm1.Button1Click(Sender: TObject);
var Stream :TFileStream;
    s:integer;
    s2:string;
begin
 Stream := TFileStream.Create('c:\va.txt', fmCreate);
 s2:=edit1.Text;
 s:=length(s2); 
 Stream.Write(s,sizeof(integer)); 
 Stream.Write(s2,s);
 stream.Free;
end;


Чтение
Код

procedure TForm1.Button2Click(Sender: TObject);
var Stream :TFileStream;
    s:integer;
    s2:string;
begin
 Stream := TFileStream.Create('c:\va.txt', fmOpenRead);
 stream.ReadBuffer(s,sizeof(integer));
 stream.ReadBuffer(s2,s);
 showMessage(s2)  ;
 stream.Free;
end;

Автор: Snowy 9.8.2007, 11:10
Код

Stream.Write(s[1],sizeof(integer)); 
Код

  SetLength(s2, s);
  stream.ReadBuffer(s2[1],s);


Добавлено через 56 секунд
А ещё есть классы TWriter и TReader...

Автор: Burka 9.8.2007, 11:18
я вот не понял, что это значит? если ссчитать что s:integer.
Код

Stream.Write(s[1],sizeof(integer)); 


SetLength(s2, s); - это хорошо) но предполагается что я не знаю длинны строки, когда читаю, то есть сначала ее тоже нужно прочитать из файла.

Добавлено через 14 минут и 54 секунды
Вот так работает. длинну еще на 1 приходитсмя увеличивать, а то он символа не дочитывает. 
Код

stream.ReadBuffer(s,sizeof(integer));
setlength(s2,s+1);
stream.ReadBuffer(s2,s);

Автор: Snowy 9.8.2007, 11:34
В первой перепутал - не ту строку поправил. Просто в моих программах обычно s - это string smile
Код

procedure TForm1.Button1Click(Sender: TObject);
var Stream :TFileStream;
    s:integer;
    s2:string;
begin
 Stream := TFileStream.Create('c:\va.txt', fmCreate);
 s2:=edit1.Text;
 s:=length(s2); 
 Stream.Write(s,sizeof(integer)); 
 Stream.Write(s2[1],s);
 stream.Free;
end;
А второй выглядит так:
Код

procedure TForm1.Button2Click(Sender: TObject);
var Stream :TFileStream;
    s:integer;
    s2:string;
begin
 Stream := TFileStream.Create('c:\va.txt', fmOpenRead);
 stream.ReadBuffer(s,sizeof(integer));
  SetLength(s2, s);
 stream.ReadBuffer(s2[1],s);
 showMessage(s2)  ;
 stream.Free;
end;

Автор: Burka 9.8.2007, 11:45
ок, так тоже работает)
про S2[1] просто не думал даже) тперь буду знать.

Автор: Snowy 9.8.2007, 11:57
Цитата(Burka @  9.8.2007,  11:45 Найти цитируемый пост)
ок, так тоже работает)
Не так тоже, а именно так и работает.
А вот так stream.ReadBuffer(s2,s); не работает.
А если работает, то только до перезапука программы. И некорректно.
Ибо ты не считываешь строку, а просто читаешь указатель.
В итоге у тебя s2 просто указывает на ту строку в памяти, которую ты до этого писал.
То есть не берёт её из файла, а ссылается на строку, которая уже сидит в памяти, ибо ты просто прочитал указатель на неё. А тебе нужно читать строку.

Цитата(Burka @  9.8.2007,  11:45 Найти цитируемый пост)
про S2[1] просто не думал даже) тперь буду знать.
Просто отдавать в Write/Read нужно блок памяти. А стринг по сути указатель на эту память.
Можно не s2[1], а по честному разыменовать указатель:
Код
    Stream.Write(pointer(s2)^, s);
Но s2[1] просто короче по записи, да и результат идентичен, т.к. по сути pointer(s2)^ как раз и указывает на s2[1].

Автор: Burka 9.8.2007, 13:28
Все ясно, Спасибо, что объеснил!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)