5 / 5 / 0
Регистрация: 08.07.2010
Сообщений: 233

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

03.12.2015, 09:30. Показов 10172. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru