Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/47: Рейтинг темы: голосов - 47, средняя оценка - 4.89
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233

Сохранить класс в файл

03.12.2015, 09:30. Показов 10022. Ответов 97
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сохранение и загрузку делаю так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
TFisherMan = class// Класс Рыбак
    NameMan:string;//Имя
    SkillMen:Integer;//Опыт
      //В рюкзаке
      NajivkaMen:array of string;//Наживки
  end;
type
  MyFile = record
    FMyFile:TFisherMan;
  end;
//*************************************************************************
var
  FisherMan:TFisherMan;
  ManFile:file of MyFile; //файл типа записи Man
  ManDann: MyFile; {переменная типа записи ManDann для работы с файлом}
 
procedure SaveFisherMan();
var
  DirSave:string;
begin//Сохранить рыбака в Файл
  //DirSave:=Dir+'Save\'+FisherMan.NameMan+'.DAN';
  DirSave:=Dir+'Save\'+klyv.Combobox1.text+'.DAT';
  ManDann.FMyFile:=FisherMan;
  AssignFile(ManFile, DirSave);//связываем файловую переменную с файлом
  rewrite(ManFile); //открываем файл для записи
  write(ManFile, ManDann); //записать в файл созданный элемент Man
  ManDann.FMyFile:=nil;
  close(ManFile); //закрываем файл
end;
procedure LoadFisherMan();
var
  DirLoad:string;
  nN, nU:Integer;
begin //загрузить рыбака из файла
  DirLoad:=Dir+'Save\'+Klyv.ComboBox1.Text+'.DAT';
  //очистить рыбака
  FisherMan:=TFisherMan.Create;
  AssignFile(ManFile, DirLoad);//связываем файловую переменную с файлом
  Reset(ManFile);//открываем файл для чтения
  read(ManFile, ManDann);//считываем из файла очередной элемент в переменную ManDann
  FisherMan:=ManDann.FMyFile;
  close(ManFile); //закрываем файл
end;
Вроде сохраняет нормально, но файл *.DAT содержит «А<Z ».
Загружает тоже без ошибок, но переменная FisherMan пустая.
Что я делаю не так?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.12.2015, 09:30
Ответы с готовыми решениями:

Сохранить файл в UTF8
Здравствуйте. Имеется функция сохранения файла: procedure TForm1.Button3Click(Sender: TObject); var t: TextFile; begin ...

Сохранить файл из memo
Как сохранить текст из поля Memo в файл, используя системный диалог SaveDialog

Открыть и сохранить файл
Здравствуйте. Есть программа в которой необходимо считать данные из файла .db, затем провести с ними расчеты и сохранить в этот же bd или в...

97
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
04.12.2015, 13:40  [ТС]
Студворк — интернет-сервис помощи студентам
Получается что динамический массив невозможно сохранить?
Нужно обязательно определять размер массива?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
04.12.2015, 13:52
вполне возможно и как раз с использованием псевдосвойства, о котором идет речь в ликбезе и который ты упорно не желаешь штудировать, ссылаясь на якобы "заумность"

Добавлено через 8 минут
пример

Не по теме:

Почему я должен за тебя искать примеры ?

1
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
04.12.2015, 14:53  [ТС]
Спасибо большое за пример.
Как-то все запутанно, может потому, что в первый раз столкнулся.
Теперь буду пытаться разложить все по полочкам.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
04.12.2015, 15:27
Цитата Сообщение от glyk5 Посмотреть сообщение
Как-то все запутанно, может потому, что в первый раз столкнулся
Вот когда столкнешься в 100500-й раз, к тому моменту ты устанешь восхищаться как все на самом деле просто, стройно и изящно.
0
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
07.12.2015, 10:34  [ТС]
Наверное у меня ума не хватает. Все выходные сидел пытался разобраться, но ничего та и не вышло.
Понял только что нужен еще один класс типа TPersistent, но так и смог его прикрутить.
Delphi
1
2
3
4
5
6
7
8
9
10
TMyClass = class(TPersistent)
  private
    Ar: Array of string;
  end;
 
  FNajivkaMen of  TMyClass;
 
  TFisherMan = class(TComponent)//*Класс Рыбак
  published
    property NajivkaMen:TMyClass  read FNajivkaMen write FNajivkaMen;
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
07.12.2015, 11:15
Цитата Сообщение от glyk5 Посмотреть сообщение
Понял только что нужен еще один класс типа TPersistent, но так и смог его прикрутить
Не нужен он там.
0
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
07.12.2015, 13:09  [ТС]
Вот так будет работать?:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  TFisherMan = class(TComponent)//*Класс Рыбак
  protected
    procedure DefineProperties(Filer: TFiler); override;
  private
    FNajivkaMen:array of string;
    FNameMan:string;
    FSkillMen:Integer;
    procedure ReadList(Reader: TReader);
    procedure WriteList(Writer: TWriter);
  published
    property NameMan:string  read FNameMan write FNameMan;//Имя
    property SkillMen:Integer read FSkillMen write FSkillMen;//Опыт
 
procedure TFisherMan.ReadList(Reader: TReader);
var
  i:Integer;
begin
  Reader.ReadValue;
  while not Reader.EndOfList do
  begin
    Reader.ReadListBegin;
    while not Reader.EndOfList do
      begin
        FNajivkaMen[i]:=Reader.ReadString;
      end;
    Reader.ReadListEnd;
  end;
end;
 
procedure TFisherMan.WriteList(Writer: TWriter);
var
  i:Integer;
begin
  Writer.WriteListBegin;
  for i:=0 to Length(FNajivkaMen)-1 do
    begin
     Writer.WriteString(FNajivkaMen[i]);
    end;
  Writer.WriteListEnd;
end;
 
procedure TFisherMan.DefineProperties(Filer: TFiler);
begin
 inherited;
 Filer.DefineProperty('NajivkaMen', ReadList, WriteList, true);
end;
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
07.12.2015, 13:29
Не будет.

При сохранении в методе WriteList нужно записать длину массива (Writer.WriteInteger) и следом в цикле записать сами элементы массива (Writer.WriteString)

При восстановлении в методе ReadList нужно прочитать длину массива (Reader.ReadInteger), затем установить длину массива равной прочитанной и, если она не нулевая, следом в цикле прочитать сами элементы массива (Reader.ReadString)
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
07.12.2015, 13:53
что-то забрели ....

Delphi
1
2
uses
 xsuperObject;
Delphi
1
2
3
4
5
6
7
8
9
10
TFisherMan = class
  protected
  private
    FNajivkaMen:array of string;
    FNameMan:string;
    FSkillMen:Integer;
  published
    property NameMan:string  read FNameMan write FNameMan;//Имя
    property SkillMen:Integer read FSkillMen write FSkillMen;
end;
Delphi
1
2
var 
  fm1,fm2:TFisherMan;
Delphi
1
2
3
4
5
6
7
8
9
10
begin
  // сохранить fm1 - некий уже существующий объект
  ss:=TStringStream.Create(fm1.asJson);
  ss.SaveToFile('111.dat');
 
  // обратное действие - создать объект fm2 из JSON строки
  ss.loadFromFile('111.dat');
  fm2 := TFisherMan.fromJSON(ss.dataString);
  ss.free;
end;
куда еще проще-то?
пример для XExx
1
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
07.12.2015, 14:06  [ТС]
Так?
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
procedure TFisherMan.ReadList(Reader: TReader);
var
  i:Integer;
begin
  i:=Reader.ReadInteger;
  SetLength(FNajivkaMen, i);
  if i>0 then
  begin
    Reader.ReadListBegin;
    for i := 0 to Reader.ReadInteger do
      FNajivkaMen[i]:=Reader.ReadString;
 
    Reader.ReadListEnd;
  end;
end;
 
procedure TFisherMan.WriteList(Writer: TWriter);
var
  i:Integer;
begin
  Writer.WriteListBegin;
  Writer.WriteInteger:=Length(FNajivkaMen)-1;
  for i:=0 to Length(FNajivkaMen)-1 do
    begin
     Writer.WriteString(FNajivkaMen[i]);
    end;
  Writer.WriteListEnd;
end;
как обратиться к полю FNajivkaMen?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
07.12.2015, 14:44
Цитата Сообщение от glyk5 Посмотреть сообщение
Так?
Не так.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
procedure TFisherMan.ReadList(Reader: TReader);
var
  i:Integer;
begin
  i:=Reader.ReadInteger; // здесь ты читаешь из потока длину массива
  SetLength(FNajivkaMen, i); // здесь ты устанвливаешь длитну массива 
  if i>0 then
  begin
// следом за длиной массива в потоке следуют собственно данные каждого из его элементов
 
    Reader.ReadListBegin; // это нафига ?
    for i := 0 to Reader.ReadInteger do // это что за ? Ты только что прочитал длину массива, зачем ты пытаешься еще раз ее читать, если ее уже в потоке нет ?
      FNajivkaMen[i]:=Reader.ReadString; // здесь ты читаешь данные i-го элемента массива
 
    Reader.ReadListEnd; // это нафига ?
  end;
end;
 
procedure TFisherMan.WriteList(Writer: TWriter);
var
  i:Integer;
begin
  Writer.WriteListBegin; // это нафига ?
  Writer.WriteInteger:=Length(FNajivkaMen)-1; // в поток нужно записать длину массива, почему минус единица-то ? 
  for i:=0 to Length(FNajivkaMen)-1 do
    begin
     Writer.WriteString(FNajivkaMen[i]);
    end;
  Writer.WriteListEnd;// а это  ?
end;
Цитата Сообщение от glyk5 Посмотреть сообщение
как обратиться к полю FNajivkaMen?
Не надо к нему обращаться напрямую - это защищенное поле.
Объяви вспомогательный тип данных

В классе TFisherMan объяви публичное индексное св-во типа String и уже к этому свойству обращайся для чтения/записи эл-та массива по указанному индексу.

Добавлено через 17 минут

Не по теме:

Цитата Сообщение от krapotkin Посмотреть сообщение
куда еще проще-то?
А откуда этот СупурПуперОбъект при рантайм-маршаллинге возьмет данные о дин.массиве, если он даже в RTTI не фигурирует ?

Рантайм-маршаллинг же верхом сидит на RTTI, а без наличия инфы о типе цена ему ломаный грош в базарный день)

1
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
07.12.2015, 15:59  [ТС]
не работает:
Delphi
1
2
published
    property NajivkaMen[index:Integer]:string read FNajivkaMen write FNajivkaMen
теперь правильно?
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
procedure TFisherMan.ReadList(Reader: TReader);
var
  i:Integer;
begin
  i:=Reader.ReadInteger;
  SetLength(FNajivkaMen, i);
  if i>0 then
  begin
    for i := 0 to Reader.ReadInteger do
      FNajivkaMen[i]:=Reader.ReadString[i];
  end;
end;
 
 
procedure TFisherMan.WriteList(Writer: TWriter);
var
  i:Integer;
begin
  Writer.WriteInteger:=Length(FNajivkaMen);
  for i:=0 to Length(FNajivkaMen)-1 do
    begin
     Writer.WriteString(FNajivkaMen[i]);
    end;
end;
Добавлено через 20 минут
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    function GetNajivkaMen(index: Integer): string;
    procedure SetNajivkaMen(index: Integer; const Value: string);
  published
    property NajivkaMen[index:Integer]:string read GetNajivkaMen write SetNajivkaMen;
 
function TFisherMan.GetNajivkaMen(index: Integer): string;
begin
 Result:= FNajivkaMen[Index];
end;
 
procedure TFisherMan.SetNajivkaMen(index: Integer; const Value: string);
begin
  FNajivkaMen[Index]:= Value;
end;
Так?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
07.12.2015, 16:11
Цитата Сообщение от glyk5 Посмотреть сообщение
не работает..
теперь правильно?
Неправильно.

Публичное свойство - это public property.
А published property - это опубликованое (не путать с публичным !) свойство.

Публичные свойства не участвуют в неявном маршаллинге - для св-ва NajivkaMen он тебе и не нужен, потому что за это отвечает одноименное виртуальное свойство, объявляемое в рантайм при выполнении строки
Delphi
1
Filer.DefineProperty('NajivkaMen', ReadList, WriteList, true);
Добавлено через 3 минуты

Не по теме:

Долго ты еще будешь биться лбом в миску аки слепой котенок ?) Неужели не надоело и не мучает совесть ?)
Все это расчудесно описано в любом приличном учебнике, давно уже пора проштудировать его .

1
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
07.12.2015, 22:00
ок. для неверующих вот код вместе с exe.
1) все public поля выводятся в файл
2) динамические массивы тоже
3) массивы все равно надо заменять на TStringList
Вложения
Тип файла: 7z 4.7z (2.60 Мб, 8 просмотров)
1
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
07.12.2015, 22:51
Цитата Сообщение от krapotkin Посмотреть сообщение
3) массивы все равно надо заменять на TStringList
Любое ограничение делает предложенную альтернативу в виде СуперОбъекта заведомо неравноценной.

Мало того - СуперОбъект не сохраняет ни инф-цию о классе сохраняемого объекта, ни о типах сохраняемых членов объекта.
Соответственно без доп.телодвижений автоматическое воссоздание сохраненного объекта с контролем типов невозможно.
Ну а раз невозможно, то какая нафих разница - что в СуперОбъекте совершать эти доп.телодвижения, что в родном сериализаторе декларировать в файлере вирт.свойства ?
При прочих равных условиях родной сериализатор вкупе с родным механизмом регистрации классов выглядит надежнее+универсальнее+экономнее

Преимущество же всяких жисонов и хмл'ов становится очевиднее лишь при необходимости упрощения переноса объектов между разными платформами разработки
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
07.12.2015, 23:10
Цитата Сообщение от mss Посмотреть сообщение
массивы все равно надо заменять на TStringList
в примере именно массив. про замену добавил "по жизни", т.к. это сильно упрощает код

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

вот именно механизм регистрации и неочевидные подкостыливания DefineProps не дали сильно развиться сохранению в "родной формат" dfm

но, как говорится, хозяин - барин
0
5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233
08.12.2015, 07:43  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Не по теме:
Долго ты еще будешь биться лбом в миску аки слепой котенок ?).
По вашему я должен все бросить и делать через"5 точку"?

Цитата Сообщение от mss Посмотреть сообщение
Не по теме:
Неужели не надоело и не мучает совесть ?).
Почему меня должна мучить совесть? Потому что я пытаюсь изучить что-то новое,а не стоять на месте?

Цитата Сообщение от mss Посмотреть сообщение
Не по теме:
Все это расчудесно описано в любом приличном учебнике, давно уже пора проштудировать его .
Ни в одном учебнике не читал про "Сериализация объектов" ввиду отсутствия сего(Может я не то читаю?). Скажите пару учебников, где описано сие "чудо".
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
08.12.2015, 08:41
Цитата Сообщение от krapotkin Посмотреть сообщение
зачем контроль типов, если десериализатор и так работает?
а уж восстанавливать в тот объект, который сохранялся, это думаю программист должен и так
Предположи гипотетически ситуацию, что Дклфи сидит не на своем родном сериализаторе. а на СуперОбъект-подобном.

По твоей логике программист, например, открывая в дизайн-тайм ранее сохраненный свой проект с формой, должен сначала каким-то невенроятным образом создать объект-форму нужного заведомо известного класса (это ему на лбу что ли придется татуировку делать, чтобы не забыть класс формы между сеансами проектирования приложения?) , а потом каким-то образом дать отмашку сериализатору, чтобы он восстановил ранее сохраненные ее св-ва из dfm или чего-то там еще.

Применительно к твоему конкретному примеру с СупеОбъектом придется проделать следующее:

fm := TForm1.Create.FromJSON(ss.DataString);

Выделенный жирным вызов конструктора обязателен, потому как суперОбъект сидит верхом непосредственно на TObject, ничего не зная о необходимости вызова конкретного конструктора конкретного наследника TForm1, в теле которого тот стринглист собссно и создается.
Т.е. ни
Delphi
1
fm := TForm.FromJSON(ss.DataString);
ни
Delphi
1
fm := TForm1.FromJSON(ss.DataString);
не воссоздадут ранее сохраненную форму в оригинальном ее виде (с существующим и заполненным стринглистом), что ведет к граблям большия и малыя)
1
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
08.12.2015, 10:01
автор пишет делфи?
имхо для каждого дела можно иметь свой шпицштихель
в учебниках в основном разбираются для хранения
-типизированные файлы
-текстовые форматы key=value по образу Ini
-XML, JSON
-база данных
и только в учебнике по созданию компонентов делфи - DefineProperties
-Случайность? Не думаю... )))"
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
08.12.2015, 11:19

Не по теме:

Цитата Сообщение от krapotkin Посмотреть сообщение
автор пишет делфи?
Автор обязан знать имеющуюся матчасть, прежде чем сравнивать и принимать решение о выборе того или иного механизма)

Цитата Сообщение от krapotkin Посмотреть сообщение
и только в учебнике по созданию компонентов
В дыру такие учебники, высвечивающие лишь малый шматок узкоспециальных знаний из контекста общефундаментальных)



Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от glyk5 Посмотреть сообщение
я должен все бросить и делать через"5 точку"?
Как раз этого я меньше всего и желаю)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.12.2015, 11:19

Сохранить файл в папке
Есть программа,и она сохраняет данные из стринггрида в эксель. Для сохранения такой код: For Col:=0 to SG2.ColCount-1 do For...

Сохранить таблицу в файл
Собрал код сохраняющий таблицу в файл, но он мне ненравится тем что он сохраняет все данные построчно. var List: TStringList; ...

Сохранить excel файл
надо как-то програмно сохранить excel файл XL := CreateOleObject('Excel.Application'); XL.DisplayAlerts := true; ...

Как сохранить файл ?
Вот мой код. procedure TForm1.N2Click(Sender: TObject); var bit:TBitmap; begin if dlgSave1.Execute() then begin ...

Сохранить цифры в файл
Здравствуйте, нужно сохранить цифры в file of byte. var f: file of byte; i: integer; b: byte; begin Write('n = '); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru