Страница 1 из 1
Сохранение объекта в файл
Добавлено: 10 ноя 2006, 15:02
Фоб
Имеется список TList, хранящий указатели на объекты разного типа.
Нужно:
1. Сохранить объекты в файл
2. Загрузить объекты из файла и снова получить TList с указателями на эти объекты.
Как это сделать?
Добавлено: 11 ноя 2006, 13:49
vunder
Обо всем по-порядку.
1) Чтобы сохранить объект в файл (поток) лучше всего прибегнуть к стандартным средствам. У класса TComponent есть методы SaveToFile (SaveToStream) и LoadFromFile (LoadFromStream). А посему свои классы нужно наследовать от TComponent.
2) По-поводу TList. Здесь получается несколько сложнее, т.к. это один из классов нижнего уровня, поэтому он нифига не умеет. Поэтому работу с сохранением/загрузкой его элементов придется реализовывать самому.
Есть еще один вариант - тот же TComponent. У него есть метод InstertComponent и свойство Components. Это можно использовать как список объектов
Добавлено: 11 ноя 2006, 17:34
Фоб
Большое спасибо! И как я сам не додумался!
Только вышло несколько по-другому:
Создаю, для примера, класс:
Код: Выделить всё
Ta = class (TComponent)
public
x: integer;
constructor Create;
end;
Записываю экземпляр в поток:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
b: Ta;
s: TMemoryStream;
begin
b:=Ta.create;
s:=TMemoryStream.create;
s.WriteComponent(b);
end;
Записывается.
Тогда как запись:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
b: Ta;
s: TMemoryStream;
begin
b:=Ta.create;
s:=TMemoryStream.create;
b.saveToStream(s);
end;
Даёт при компиляции ошибку
У экземпляра отутствует этот метод. В дельфёвом хэлпе в списке методов класса TComponent saveToStream также отсутствует.
Вопросы:
1. Почему? В TComponent точно есть saveToStream? Как его добыть? Может я класс неверно объявляю?
2. Вот такая вещь:
Код: Выделить всё
s.WriteComponent(b);
s.Position:=0;
s.ReadComponent(b);
собственно, пишет всё и читает адекватно?
3. В моих реальных объектах широко налажена ссылочность через указатели (типа pointer)...
Я пока не пробовал, но думается, что после сохранения и загрузки, пойнтеры эти будут указывать отнюдь не на мои объектики, так ведь? Может есть способ как-то сохранить пойнтеровую ссылочность при сохранении-загрузке?
Добавлено: 12 ноя 2006, 11:53
vunder
Сори. На счет методов я погорячился.
чтение:
Код: Выделить всё
function ReadEx(Instance: TComponent; Stream: TStream; LeaveName: Boolean=False): TComponent;
begin
with TReader.Create(Stream, 4096) do
try
if Assigned(Instance) and not LeaveName then Instance.Name := '';
Result := ReadRootComponent(Instance)
finally
Free
end
end;
запись:
Код: Выделить всё
function SaveToStream(Instance: TComponent; Stream: TStream): Boolean;
begin
Result := True;
Stream.WriteDescendent(Instance, nil);
end;
несколько советов:
1) для сохранения свойств они ОБЯЗАТЕЛЬНО д.б. в секции
published
2) читай справку, там все есть
Добавлено: 15 ноя 2006, 19:33
Фоб
Спасибо, всё работает.
А есть ли способ сохранять и загружать любой объект, не являющийся наследником TComponent?
То есть, чтоб происходило следующее:
Имеем экземпляр объекта - участок памяти. Берём и копируем этот участок как есть в файл. А потом, при загрузке, снова распологаем в память. Можно так?
Добавлено: 16 ноя 2006, 11:49
vunder
в общем случае - нет.
объект это не статическая запись, у него есть много различных ссылок, недоступных пользователю