Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.06;
Скачать: CL | DM;

Вниз

Как лучше реализовать запись множества дин. данный в файл?   Найти похожие ветки 

 
Maks Realov   (2005-02-22 11:27) [0]

Здравствуйте.
Хотел посоветоваться с мастерами.
Имеется следующая задача:
1). Есть много структур (десяток) и несколько динамических массивов. Все они являются полями разных классов.
2). Программа заполняет данные структур, размещает память под массивы (размер массивов естественно меняется в run time"е) и заполняет эти массивы данными.

Задача: сохранить всё это хозяйство в файле на диске.
Как это лучше сделать?
Хочется, что бы всё сохранялось в один файл и каждый класс "знал" как считать именно его данные из этого файла.

В типизированные файлы не получится, т.к. размер массивов не известен, про ini-файлы я вообще молчу.
Думал, может под данные каждого класса выделять заведомо много места и писать всё binary блоками, а читать - по смещению. Но это грубо и некрасиво.

Что можете посоветовать?


 
Erik1 ©   (2005-02-22 11:35) [1]

Можем, например создавать для записей заголовак в котором указывать размер или количество записей. Тут есть где фантазии развернутся. А Читать, писать можно через TFileStream, а можно просто блоками.


 
Maks Realov   (2005-02-22 11:37) [2]

У Подгорецкого пример уже нашёл :)
http://www.delphikingdom.com/lyceum/seminar.asp?partID=4&LessonID=15#PageTop

Никто не знает - есть где-нибудь готовый класс, что бы мне дурную работу дважды не делать?


 
begin...end ©   (2005-02-22 12:30) [3]

> Maks Realov   (22.02.05 11:37) [2]

Сделайте эту "дурную работу" сами. Ей-богу, не пожалеете. :-)

--------------------
Sorry, I"m drunk now


 
Anatoly Podgoretsky ©   (2005-02-22 13:01) [4]

Ключевое слово TPersistent, от него создаются классы сохраняющие себя в поток.


 
Maks Realov   (2005-02-22 16:02) [5]

Не понял, в чём дело:

TByteArrayType = array of byte;

procedure TTest.LoadFromFile(const StructureNumber: integer;
 var LoadToArray: TByteArrayType);
var
 Hdr: THdr;
 FS: TFileStream;
begin
 TestFileNameEstableshed();
 FS:= TFileStream.Create(FFileName, fmOpenRead or fmShareExclusive);
 try
   FS.Seek(0, soFromBeginning);
   FS.Read(Hdr, SizeOf(Hdr));
   while Hdr.RecID <> StructureNumber do // тут недоделана процедурка
   begin
     FS.Seek(Hdr.RecLg + SizeOf(Hdr), soFromCurrent);
     FS.Read(Hdr, SizeOf(Hdr));
   end;
   FS.Seek(SizeOf(Hdr), soFromCurrent);
   SetLength(LoadToArray, Hdr.RecLg);
   FS.ReadBuffer(arr, Hdr.RecLg); //читается какой-то маразм
 finally
   FS.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 arr2: TByteArrayType;
 Test: TTest;
begin
 //...
 Test.LoadFromFile(1, arr2);
 CopyMemory(@Test, arr2, Length(arr2));
end;


Если использую не дин. а стат. массив, то всё нормально.
Это что, из-за того, что в Delphi динамический массив является тоже классом, как и string? И первые сколько-то байт под размер и счётчик отведены? Я в Delphi слаб ещё, так что не ругайте, если что :-)


 
Maks Realov   (2005-02-22 16:02) [6]

Не понял, в чём дело:

TByteArrayType = array of byte;

procedure TTest.LoadFromFile(const StructureNumber: integer;
 var LoadToArray: TByteArrayType);
var
 Hdr: THdr;
 FS: TFileStream;
begin
 TestFileNameEstableshed();
 FS:= TFileStream.Create(FFileName, fmOpenRead or fmShareExclusive);
 try
   FS.Seek(0, soFromBeginning);
   FS.Read(Hdr, SizeOf(Hdr));
   while Hdr.RecID <> StructureNumber do // тут недоделана процедурка
   begin
     FS.Seek(Hdr.RecLg + SizeOf(Hdr), soFromCurrent);
     FS.Read(Hdr, SizeOf(Hdr));
   end;
   FS.Seek(SizeOf(Hdr), soFromCurrent);
   SetLength(LoadToArray, Hdr.RecLg);
   FS.ReadBuffer(arr, Hdr.RecLg); //читается какой-то маразм
 finally
   FS.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 arr2: TByteArrayType;
 Test: TTest;
begin
 //...
 Test.LoadFromFile(1, arr2);
 CopyMemory(@Test, arr2, Length(arr2));
end;


Если использую не дин. а стат. массив, то всё нормально.
Это что, из-за того, что в Delphi динамический массив является тоже классом, как и string? И первые сколько-то байт под размер и счётчик отведены? Я в Delphi слаб ещё, так что не ругайте, если что :-)


 
Maks Realov   (2005-02-22 16:05) [7]


CopyMemory(@Test, arr2, Length(arr2));

- сорри, это уже не из той оперы :-)


 
begin...end ©   (2005-02-22 16:08) [8]

> Maks Realov   (22.02.05 16:02) [6]

> FS.ReadBuffer(arr, Hdr.RecLg)

FS.ReadBuffer(LoadToArray[0], Hdr.RecLg)


 
Maks Realov   (2005-02-22 16:28) [9]

О!
Спасибки!
Значит переменная типа дин. массив - это указатель на указатель на первый элемент :-) Так?


 
begin...end ©   (2005-02-22 16:35) [10]

> Maks Realov   (22.02.05 16:02) [6]
> в Delphi динамический массив является тоже классом,
> как и string

В Delphi тип string не является классом.

> Maks Realov   (22.02.05 16:28) [9]
> Значит переменная типа дин. массив - это указатель на
> указатель на первый элемент :-) Так?

Нет. Переменная типа динамический массив - это указатель на первый (нулевой) элемент. А в [6] Вы читали из файла не в область, где расположены элементы массива, а в этот указатель.



Страницы: 1 вся ветка

Текущий архив: 2005.03.06;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.031 c
1-1108625387
JohnS
2005-02-17 10:29
2005.03.06
TWebBrowser


1-1108899749
Jel
2005-02-20 14:42
2005.03.06
Показать SQL Builder в Run-Time


14-1108362889
_silver
2005-02-14 09:34
2005.03.06
Вот я и женился.


6-1103727459
frEE)stylEr
2004-12-22 17:57
2005.03.06
Twebbrowser


14-1108366803
Sapsi
2005-02-14 10:40
2005.03.06
Уровень общей культуры в России и других странах