![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Запись 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;
Для нескольких экземпляров записей поступаешь по схеме: открыл поток - записал/прочитал поочередно все элементы - закрыл поток.
В таком духе.