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

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

Позволяет ли ClientDataSet хранить несколько таблиц в одном файле


Tahion2 ©   (2003-07-28 20:38:00) 

Позволяет ли ClientDataSet хранить несколько таблиц в одном файле?


Dred2k   (2003-07-29 19:03:00) [1]

Да, чуть не забыл. Реализацию методов SaveToStream и LoadFromStream нужно "подглядеть" в исходнике модуля (для разных версий дельфи возможны отличия, при написании компонента в общем виде - не забыть про версии компилера...).


Dred2k   (2003-07-29 18:49:00) [2]

Последовательные чтения после последовательной записи действительно по умолчанию хватают чужие данные... Но, на самом деле есть простое и красивое решение данной проблемы.

Объект TClientDataSet внутри уже приспособлен для записи и восстановления из потока, содержащего данные нескольких датасетов. Только ему нужно чуть-чуть помочь ;)
Все дело в том, что методы SaveToStream и LoadFromStream вызывают protected-методы WriteDataPacket и ReadDataPacket соответсвенно. Самое интересное, что у последних есть два параметра: (Stream: TStream; Write(Read)Size: Boolean);
Последний вам ни о чем не говорит? ;)
Таким образом, делаем наследника следующего вида:


interface

TClientDataSetEx = class(TClientDataSet)
public
procedure SaveToStreamEx(AStream : TStream; AWriteSize : Boolean);
( AStream : TStream; AReadSize : Boolean)

Последовательные чтения после последовательной записи действительно по умолчанию хватают чужие данные... Но, на самом деле есть простое и красивое решение данной проблемы.

Объект TClientDataSet внутри уже приспособлен для записи и восстановления из потока, содержащего данные нескольких датасетов. Только ему нужно чуть-чуть помочь ;)
Все дело в том, что методы SaveToStream и LoadFromStream вызывают protected-методы WriteDataPacket и ReadDataPacket соответсвенно. Самое интересное, что у последних есть два параметра: (Stream: TStream; Write(Read)Size: Boolean);
Последний вам ни о чем не говорит? ;)
Таким образом, делаем наследника следующего вида:


interface

TClientDataSetEx = class(TClientDataSet)
public
procedure SaveToStreamEx(AStream : TStream; AWriteSize : Boolean);
procedure LoadFromStreamEx(AStream : TStream; AReadSize : Boolean);
end;

implementation

procedure TClientDataSetEx.SaveToStreamEx(AStream: TStream; AWriteSize : Boolean);
begin
WriteDataPacket(AStream, AWriteSize);
end;

procedure TClientDataSetEx.LoadFromStreamEx(AStream: TStream; AReadSize : Boolean);
begin
Close;
ReadDataPacket(AStream, AReadSize);
Open;
end;


Далее делаем компонент. Ставим на палитру и используем его.
Либо, при операции записи-чтения создаем временные объекты нового типа и через них пишем-читаем (Data кидаем туда-обратно, но это не особо эффективно по ресурсам и производительности).
Пример приведен для D4 (в D6 есть еще тип потока, но это не принципиально - передаем как есть). Разумеется, не следует забывать о последовательности записей-чтений. Кроме того, при этом можно между потоками информации датасетов размещать "хрень" по вкусу. ;)
Ну, вот и все.


Serginio   (2003-07-29 16:33:00) [3]

Намного проще вначале прописать интежер (4 байта) с размером стрима затем сам стрим, затем прочитать это количество байт в лученное св-во Data (посмотреть исходники LoadFromStream) и так для каждого ClientDataSet.
Также и с информацией про ее отображение.


Reindeer Moss Eater   (2003-07-29 15:59:00) [4]

скорее всего 1 вызов попытается "заглотить чужие данные",
Такой вывод можно сделать только зная формат.


Polevi   (2003-07-29 15:57:00) [5]

2Reindeer Moss Eater (29.07.03 15:38)
сомневаюсь что будет работать, скорее всего 1 вызов попытается "заглотить чужие данные", наверняка промежуточный поток потребуется


Reindeer Moss Eater   (2003-07-29 15:38:00) [6]

как, пользуясь Stream-ами, загрузить две разные таблицы из одного файла?

ClientDataSet1.LoadFromStream(Stream1);
ClientDataSet2.LoadFromStream(Stream1);


Tahion2   (2003-07-29 15:36:00) [7]

Polevi, а можно пример того, как, пользуясь Stream-ами, загрузить две разные таблицы из одного файла?

***********
Несколько похожий вопрос:

…
ClientDadaSet1.SaveToFile(‘c:\1.cds’);

Как сделать так, чтоб помимо самой таблицы, в файле еще сохранялись и информация про ее отображение. Т.е. порядок столбцов, ширина столбцов, DisplayLabel и т.п.

И как потом эту информацию правильно загружать?

Обсуждается тут:
http://www.delphimaster.ru/cgi-bin/forum.pl?look=1&id=1059478003&n=1


Polevi   (2003-07-29 12:38:00) [8]

свой формат, в заголовке хранить колво датасетов и смещение каждого от начала


Reindeer Moss Eater   (2003-07-29 12:13:00) [9]

Может есть какой-либо усовершенствованный компонент - ClientDataSet с возможностью сохранить и загрузить несколько таблиц из одного файла?

И куда их грузить если например структура таблиц разная?
А если одинаковая, то зачем несколько таблиц?


Reindeer Moss Eater   (2003-07-29 12:03:00) [10]

Позволяет ли ClientDataSetхранить несколько таблиц в одном файле?

Конечно позволяет. А все потому, что хранением он не занимается.


Tahion2   (2003-07-29 11:46:00) [11]

>интересно а обратно считает?

Во, во.
У кого-нибудь есть пример кода, как сохранить несколько таблиц в один файл, а потом ОТКРЫТЬ их из него?

P.S. Может есть какой-либо усовершенствованный компонент - ClientDataSet с возможностью сохранить и загрузить несколько таблиц из одного файла?


sniknik   (2003-07-29 00:46:00) [12]

интересно а обратно считает?

(это не сарказм и не прикол, действительно не знаю, и в голову не приходило так делать и проверять тоже не хочу, ввиду прогнозируемости результата. но может кто пробовал? а вдруг)


AkaSaint   (2003-07-28 21:44:00) [13]

Да, делаешь им всем SaveToStream в один и тот же поток, где Stream: TFileStream, например.


Наверх

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