Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Сохранение структуры


Автор: ASGDeveloper 21.6.2006, 11:26
Есть у меня структура такого типа:
Код

type
  LI = Longint;
  BT = string[100];
  U = ^BinTree;
  BinTree = record
    Inf: BT;
    Scope: LI;
    L, R: U
  end;

и есть переменная:
Код

var
BinaryTree : U;

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

Автор: skyboy 21.6.2006, 11:41
а ты перед обращением создал эту свою binarytree?
Это же ссылочный тип, потому перед обращением надо
Код

BinaryTree:= new(U);

а добавлять ветви:
Код

BinaryTree.L:= new(U);
BinaryTree.R:= new(U);
 

Автор: ASGDeveloper 21.6.2006, 11:54
Цитата(skyboy @  21.6.2006,  11:41 Найти цитируемый пост)
а ты перед обращением создал эту свою binarytree?

Конечно! Меня интересует конкретно сохранение.
Я пробовал через типизированные файлы. Но пока остановился (как временное решение) на сохранение и загрузку через TStrings. 

Автор: Snowy 21.6.2006, 12:00
А TStrings то тут каким боком???
Типизированные файлы вполне подойдут.
Думаю, что вопрос скорее не в сохранении, а в последующем чтении.
С сохранением вопросов быть не должно. 

Автор: skyboy 21.6.2006, 12:11
ASGDeveloper, я не могу угадать, в чём у тебя заключается проблема, однако, как мне кажется, не надо сохранять указатели - при следующем запуске программы, в месте, на которое "метит" ветка твоего дерева, может располагаться объект "кнопка" или ещё чего. Сделай сохранение вложенности через скобки. Или через какое-то id, а при загрузке из файла создавай ветви при помощи new. 

Автор: ASGDeveloper 21.6.2006, 12:14
Цитата(Snowy @  21.6.2006,  12:00 Найти цитируемый пост)
А TStrings то тут каким боком???

Дык просто перебираю элементы дерева и сохраняю smile


Цитата(Snowy @  21.6.2006,  12:00 Найти цитируемый пост)
Думаю, что вопрос скорее не в сохранении, а в последующем чтении.
С сохранением вопросов быть не должно.

Абсолютно верно! smile

Добавлено @ 12:18 
Цитата(skyboy @  21.6.2006,  12:11 Найти цитируемый пост)
я не могу угадать, в чём у тебя заключается проблема, однако, как мне кажется, не надо сохранять указатели - при следующем запуске программы, в месте, на которое "метит" ветка твоего дерева, может располагаться объект "кнопка" или ещё чего.

Нет, конечно я не сохраняю указатель. Ведь U - это всегда 4 байта, а BinTree - сколько угодно. 

Была попытка сохранять так:
Код

var
F: file of BinTree;
S: BinTree;

AssignFile(F,fileName); 
rewrite(F);
write(F,S);
CloseFile(F);


и грузить так:
Код

var
F: file of BinTree;
S: BinTree;

AssignFile(F,fileName); 
reset(F);
read(F,S);
CloseFile(F);


Не катит.  

Автор: Snowy 21.6.2006, 12:20
Нужно указатель после чтения устанавливать.
Указатели при каждом запуске указывают в разное место, так что нет смысла их читать.
После чтения нужно прописать новое значение в указатели L и R.

Добавлено @ 12:22 
В остальном всё верно. 

Автор: ASGDeveloper 21.6.2006, 13:13
Цитата(Snowy @  21.6.2006,  12:20 Найти цитируемый пост)
В остальном всё верно.

Ну вообщем вынес s в глобальные переменные и модифицировал код:
(запись)
Код

      if BinaryTree = nil then
        exit;
      s := BinTree(BinaryTree^);

(чтение)
Код

BinaryTree := @S;

Теперь вроде заработало, но слхраняет только первый элемент дерева. smile
Или грузит только первый, что менее вероятно. 

Автор: skyboy 21.6.2006, 14:58
ASGDeveloper, повторяю после себя и  Snowy: после загрузки из файла указатели в L и R указывают куда угодно, но только не на следующие ветви! Тебе нет смысла сохранять восстанавливать поля L и R, потому как после загрузки их ты использовать не сможешь. Никак. Тебе надо заново резервировать память! Поэтому ещё хорошо, что у тебя обращается только к первой ветви, а остальных вроде и нет. Я думал, что при такой загрузке ты получишь Access Violation при попытке перехода по ссылкам L или/и R. 

Автор: Snowy 21.6.2006, 15:39
Тут смысл в другом.
Человек не знает, КАК вообще сохранить дерево.
Как нужно:
Код

type
  TBinTree = class(TPersistent)
  private
    FInf: string;
    FScope: LongInt;
    FL: TBinTree;
    FR: TBinTree;
  published
    property Inf: string read FInf write FInf;
    property Scope: LongInt read FScope write FScope;
    property L: TBinTree read FL write FL;
    property R: TBinTree read FR write FR;
  end;

  TBinaryTree = class(TComponent)
  private
    ......
    FRoot: TBinTree;
  public
  ...
    function SaveBinaryTree(FileName: string): Boolean;
    function LoadBinaryTree(FileName: string): Boolean;
  published
    property Root: TBinTree read FRoot write FRoot;
  end;

.....

function TBinaryTree.SaveBinaryTree(FileName: string): Boolean;
var fs: TFileStream;
begin
  try
    fs := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite);
    fs.WriteComponent(Self);
    fs.Free;
    result := true;
  except result := false;
end;

function TBinaryTree.LoadBinaryTree(FileName: string): Boolean;
var fs: TFileStream;
begin
  try
    fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
    try
      fs.ReadComponent(Self);
      result := true;
    finally
      fs.Free;
    end;
  except result := false;
end;


ЗЫ. Код не проверял - писал прямо в браузере.
Но вроде всё правильно.
Нужно только остальной код переделать со структуры и указателей на объекты.  

Автор: ASGDeveloper 21.6.2006, 15:44
Цитата(Snowy @  21.6.2006,  15:39 Найти цитируемый пост)
ЗЫ. Код не проверял - писал прямо в браузере.
Но вроде всё правильно.
Нужно только остальной код переделать со структуры и указателей на объекты.

Вау! Круто!
Спасибо огромное!
Жаль не хватает сообщений для повышения репутации. Как быдет, тогда повышу. ок? smile

ЗЫ Еще раз спасибо. 

Автор: Snowy 21.6.2006, 15:47
ГЫ. Забыл.
В публишед секциях перед именем нужно еще написать property.
If поправлю. 

Автор: ASGDeveloper 26.6.2006, 11:37
Цитата(Snowy @  21.6.2006,  15:39 Найти цитируемый пост)
ЗЫ. Код не проверял - писал прямо в браузере.
Но вроде всё правильно.

При загрузке более одного элемента ругается на invalid property path. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)