|
|
#1
|
||||
|
||||
StringList в файл
Люди, подскажите плиз, как сохранить 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-строками фактически таже история. Нам надо знать сколько актуальная длина для операций сохранения/чтения в/из потока. |