![]() |
|
|
|
|
#1
|
||||
|
||||
|
Люди, подскажите плиз, как сохранить TStringList в составе record в файл? У меня сохраняется указатель вместо содержимого
![]() |
|
#2
|
|||
|
|||
|
Не понял на счёт record'а, но строки сохранить можно так:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
SL1: TStringList;
begin
SL1:= TStringList.Create;
SL1.AddStrings(ListBox1.Items); // в ListBox'е был текст
SL1.SaveToFile('mylist.txt');
SL1.Free;
end; |
|
#3
|
||||
|
||||
|
в составе record это типа так:
Код:
type MyFile=record
val1:integer;
val2:string[20];
StrList:TStringList
end;
//а затем
procedure Save(FileName : string);
var OutF : file of MyFile;
begin
...
end; |
|
#4
|
|||
|
|||
|
Цитата:
Естественно, у тебя таким образом сохраняется указатель. И подругому тут ничего не сделаешь. Варианты решения: 1. В записи хранить String, а для работы в StringList пихать его в StringList.Textэ 2. Отказаться от File Of и писать через TFileStream. В этом случае у тебя полный контроль над тем как и что ты сохраняешь. Все дело в том, что File Of работает с записями фиксированной длинны, а у тебя содержимое StringList потенциально может быть различной длинны. Если есть вопросы - wellcome. |
|
#5
|
||||
|
||||
|
1 способ не подходит...а вот второй как раз да. Тока как потоки юзать?
|
|
#6
|
|||
|
|||
|
Цитата:
Код:
procedure SaveToFile(AData : MyFile);
var
Stream : TFileStream;
StrLen : Integer;
SLStr : String;
begin
Stream := TFileStream.Create('MyFile.dat',fmCreate);
Try
Stream.WriteBuffer(AData.val1,SizeOf(Integer));
StrLen := Length(AData.va2);
Stream.WriteBuffer(StrLen,SizeOf(Integer));
Stream.WriteBuffer(AData.val2[1],StrLen);
SLStr := AData.StrList.Text;
StrLen := Length(SLStr);
Stream.WriteBuffer(StrLen,SizeOf(Integer));
Stream.WriteBuffer(SLStr[1],StrLen);
Finally
Stream.Free;
End;
end;
procedure LoadFromFile(var AData : MyData); // запись должна быть создана, в т.ч. и StringList в ней.
var
Stream : TFileStream;
StrLen : Integer;
SLStr : String;
begin
Stream := TFileStream.Create('MyFile.dat',fmRead);
Try
Stream.ReadBuffer(AData.val1,SizeOf(Integer));
Stream.ReadBuffer(StrLen,SizeOf(Integer));
Stream.ReadBuffer(AData.val2[1],StrLen);
Stream.ReadBuffer(StrLen,SizeOf(Integer));
SetLength(SLStr,StrLen);
Stream.ReadBuffer(SLStr[1],StrLen);
AData.Text := SLStr;
Finally
Stream.Free;
End;
end;Фокус тут только в одном - перед записью строки мы пишем в поток ее реальную длинну. При обратном чтении сначала читаем длинну и для SNSI строк выделяем память под данные (SetLength). Это связанно с тем, что мы не можем ограничить, например, StringList при вызове его метода LoadFromStream каким-либо кол-вом вычитываемой информации. Вот и приходится таким маневром обходить это ограничение. Впрочем, с PASCAL-строками фактически таже история. Нам надо знать сколько актуальная длина для операций сохранения/чтения в/из потока. |