Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Запись TList в файл [D7]


mfender ©   (2007-09-27 20:59:00) 

Здравствуйте.
Делаю незатейливую конструкцию и подумываю, как бы её записать в файл:


   FNRRecords: TList;

{ это запись, из которых состоит FNRRecords }
 TNRRec = ^PNRRec;
 PNRRec = record
   Category: Integer;
   Arts: TStrings;
 end;


Есть ли простой способ сохранить FNRRecords в файл? Ну и считать содержимое файла в FNRRecords


Германн   (2007-09-28 01:33:00) [1]


> Делаю незатейливую конструкцию


>  TNRRec = ^PNRRec;
>  PNRRec = record

И это ты называешь "незатейливой конструкцией"? Всё "с ног на голову" :-)


Джо   (2007-09-28 00:37:00) [2]

Хотя, конечно, если «неограниченно много», то тут даже Аллах бессилен.


Джо   (2007-09-27 22:47:00) [3]

> [2] mfender ©   (27.09.07 21:29)
> В том-то и дело, что их может быть (и есть) неограниченно
> много.

for I := 0 to List.Count-1 do


mfender   (2007-09-27 22:36:00) [4]

Ошибки были. Теперь всё правильно:


procedure TNR.SaveToFile;
var
 I, N: Integer;
 Doc: TXMLDocument;
 R, C, A: IXMLNode;
begin
 try
   Doc := TXMLDocument.Create(FOwner);
   Doc.Active := True;
   Doc.Version := '1.0';
   R := Doc.AddChild('root');
   if FNRRecords.Count > 0 then
   begin
     for I := 0 to FNRRecords.Count - 1 do
     begin
       C := R.AddChild('category');
       C.SetAttribute('oid', TNRRec(FNRRecords[i]).Category);
       if TNRRec(FNRRecords[I]).Arts.Count > 0 then
       begin
         for N := 0 to TNRRec(FNRRecords[I]).Arts.Count - 1 do
         begin
           A := C.AddChild('art');
           A.NodeValue := TNRRec(FNRRecords[I]).Arts[N];
         end;
       end;
     end;
   end;
   Doc.SaveToFile(FFileName);
 except

 end;
end;


mfender   (2007-09-27 21:29:00) [5]

В том-то и дело, что их может быть (и есть) неограниченно много.

Вобщем, решил пойти путём XML:


procedure TNR.SaveToFile;
var
 I, N: Integer;
 Doc: TXMLDocument;
 R, C, A: IXMLNode;
begin
 try
   Doc := TXMLDocument.Create(FFileName);
   Doc.Version := '1.0';
   R := Doc.AddChild('root');
   if FNRRecords.Count > 0 then
   begin
     for I := 0 to FNRRecords.Count - 1 do
     begin
       C := R.AddChild('category');
       C.NodeValue := TNRRec(FNRRecords[i]).Category;
       if TNRRec(FNRRecords[I]).Arts.Count > 0 then
       begin
         for N := 0 to TNRRec(FNRRecords[I]).Arts.Count - 1 do
         begin
           A := C.AddChild('art');
           A.NodeValue := TNRRec(FNRRecords[N]).Arts[N];
         end;
       end;
     end;
   end;
   Doc.SaveToFile(FFileName);
 except

 end;
end;


Щас посморю, какие будуть ошибки ))))

Ну, считывать тем же путём.


Джо   (2007-09-27 21:16:00) [6]

Вот примерно так, процудуры чтения/записи PNRRec в поток:

procedure SaveRecToStream (AStream: TStream; ARec: TPNRRec);
var
 Text: string;
 Ln: Integer;
begin
 AStream.Write(ARec.Category,SizeOf(ARec.Category));
 Text := ARec.Arts.Text;
 // запишем сначала длину строки, а затем саму строку
 Ln := Length(Text);
 AStream.Write(Ln,SizeOf(Ln));
 AStream.Write(Text[1],Ln)
end;

procedure LoadRecFromStream (AStream: TStream; var ARec: TPNRRec);
var
 Text: string;
 Ln: Integer;
begin
 AStream.Read (ARec.Category,SizeOf(ARec.Category));
 // Прочтем сначала длину строки
 AStream.Read(Ln,SizeOf(Ln));
 // Установим размер
 SetLength(Text,Ln);
 // И прочтем само тело строки
 AStream.Read(Text[1],Ln);
 ARec.Arts.Text := Text;
end;

Это, конечно, первое приближение. Зачастую удобней сделать PNRRec классом, а вышеприведенные процедуры — его методами.

В файл, таким образом, писать можно так:

var
 Rec: TPNRRec;
 Fs: TFileStream;
begin
 ...
 Fs := TFileStream.Create('d:\rec.dat',fmCreateNew);
 try
   SaveRecToStream(Fs,Rec);
 finally
   Fs.Free
 end;
end;


Читать:

var
 Rec: TPNRRec;
 Fs: TFileStream;
begin
 ...
 Fs := TFileStream.Create('d:\rec.dat',fmOpenRead);
 try
   LoadRecToStream(Fs,Rec);
 finally
   Fs.Free
 end;
end;


Для нескольких экземпляров записей поступаешь по схеме: открыл поток - записал/прочитал поочередно все элементы - закрыл поток.

В таком духе.


Наверх

Титульная страница Поиск, карта сайта Написать письмо