Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Файловая система
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.04.2008, 12:23
Аватар для KOOL
KOOL KOOL вне форума
Активный
 
Регистрация: 06.01.2008
Адрес: Рязань
Сообщения: 306
Версия Delphi: 2009
Репутация: 6150
По умолчанию StringList в файл

Люди, подскажите плиз, как сохранить TStringList в составе record в файл? У меня сохраняется указатель вместо содержимого
Ответить с цитированием
  #2  
Старый 23.04.2008, 12:52
AlexSku AlexSku вне форума
Специалист
 
Регистрация: 07.05.2007
Адрес: Москва
Сообщения: 884
Репутация: 21699
По умолчанию

Не понял на счёт 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  
Старый 24.04.2008, 14:11
Аватар для KOOL
KOOL KOOL вне форума
Активный
 
Регистрация: 06.01.2008
Адрес: Рязань
Сообщения: 306
Версия Delphi: 2009
Репутация: 6150
По умолчанию

в составе record это типа так:
Код:
type MyFile=record
         val1:integer;
         val2:string[20];
         StrList:TStringList
       end;
//а затем
procedure Save(FileName : string);
var OutF : file of MyFile;
begin
...
end;
все сохраняется нормально, кроме StringList
Ответить с цитированием
  #4  
Старый 24.04.2008, 14:18
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,048
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от KOOL
в составе record это типа так:
Код:
type MyFile=record
         val1:integer;
         val2:string[20];
         StrList:TStringList
       end;
//а затем
procedure Save(FileName : string);
var OutF : file of MyFile;
begin
...
end;
все сохраняется нормально, кроме StringList

Естественно, у тебя таким образом сохраняется указатель.
И подругому тут ничего не сделаешь.
Варианты решения:
1. В записи хранить String, а для работы в StringList пихать его в StringList.Textэ
2. Отказаться от File Of и писать через TFileStream. В этом случае у тебя полный контроль над тем как и что ты сохраняешь.

Все дело в том, что File Of работает с записями фиксированной длинны, а у тебя содержимое StringList потенциально может быть различной длинны.

Если есть вопросы - wellcome.
Ответить с цитированием
  #5  
Старый 28.04.2008, 19:10
Аватар для KOOL
KOOL KOOL вне форума
Активный
 
Регистрация: 06.01.2008
Адрес: Рязань
Сообщения: 306
Версия Delphi: 2009
Репутация: 6150
По умолчанию

1 способ не подходит...а вот второй как раз да. Тока как потоки юзать?
Ответить с цитированием
  #6  
Старый 28.04.2008, 19:51
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,048
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от KOOL
1 способ не подходит...а вот второй как раз да. Тока как потоки юзать?

Код:
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-строками фактически таже история. Нам надо знать сколько актуальная длина для операций сохранения/чтения в/из потока.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:01.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter