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

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

Как лучше реализовать запись множества дин. данный в файл? [D6, Win95/98, WinME, NT4, Win2k, WinXP]


Maks Realov ©   (2005-02-22 11:27:00) 

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

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

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

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


begin...end   (2005-02-22 16:35:00) [1]

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

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

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

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


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

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


begin...end   (2005-02-22 16:08:00) [3]

> 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:05:00) [4]


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

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


Maks Realov   (2005-02-22 16:02:00) [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:00) [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 слаб ещё, так что не ругайте, если что :-)


Anatoly Podgoretsky   (2005-02-22 13:01:00) [7]

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


begin...end   (2005-02-22 12:30:00) [8]

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

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

--------------------
Sorry, I'm drunk now


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

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

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


Erik1   (2005-02-22 11:35:00) [10]

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


Наверх

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