как сохранить объект в файл? delphi
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
как сохранить объект в файл? delphi - 2009-10-25 22:25:07.156666
|
|
|
Angella
Сообщений: 22
Оценки: 0
Присоединился: 2007-08-02 23:45:39.443333
|
Пытаюсь сохранить объект в файл:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
type
TClass = class(TComponent)
public
i:integer;
s:string;
end;
var
fs:TFileStream;
ms:TMemoryStream;
c:TClass;
begin
try
c.i:=1;
fs :=TFileStream.Create('111.dat', fmCreate or fmOpenWrite);
ms :=TMemoryStream.Create;
ms.WriteComponent(c);
ms.Position:=0;
ObjectBinaryToText(ms, fs);
finally
ms.Free;
fs.Free;
end;
end.
выдает MessageBox: ''accces violation at 0x7c91bfa: write of address 0x0000000f'. Process Stopped. Use Step or Run to continue. комментирую ms.free все работает. видимо в MemoryStream не сохраняется объект. + файл не создается 0_о нид хелп
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-25 23:56:07.960000
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
Вот уж не знаю иерархию объектов VLC, но предположу, что TComponent не является наследником TPersistent, и если это так, то проблема может быть вот в этом: http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_20746545.html
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 02:04:41.700000
|
|
|
alexbozhko
Сообщений: 1024
Оценки: 0
Присоединился: 2005-11-24 13:35:34
|
хм а разве c:TClass; создавать не нужно? похоже, до ms :=TMemoryStream.Create; дело и не доходит, сразу на finally уходит ну элементарно на трассу пусти
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 07:06:12.276666
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: alexbozhko а разве c:TClass; создавать не нужно? Кстати, да :) Хотя дебаггер показывает, что, что присваивание c.i := 1 проходит нормально, а вылетает дальше, на ms.WriteComponent, и что-то я туго соображаю почему. Если access violation, то он должен был вылезти как только мы попытались бы записать число 1 по случайному адресу, который оказался в неинициализированной переменной c. На оптимизацию компилятора тоже вроде не похоже. Единственное, что остаётся думать, это то, что программе было разрешено испортить память, записав данные в чужую область, но затем отказано в стении этой самой области. Так что ли?
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 12:15:12.226666
|
|
|
Angella
Сообщений: 22
Оценки: 0
Присоединился: 2007-08-02 23:45:39.443333
|
так написано выше .. var c:TClass .. или он только указатель создает? прогнал по трассе, файл создается, но ничего туда не пишется (размер файла 0кБ) кстати есть предупреждение: [DCC Warning] Project1.dpr(18): W1036 Variable 'c' might not have been initialized не понимаю почему :) с вариантом try finaly он так же предупреждал об объектах ms и fs
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 20:20:47.793333
|
|
|
alexbozhko
Сообщений: 1024
Оценки: 0
Присоединился: 2005-11-24 13:35:34
|
unit Unit6;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TClass = class(TComponent)
public
i:integer;
s:string;
end;
type
TForm6 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form6: TForm6;
implementation
{$R *.dfm}
procedure TForm6.Button1Click(Sender: TObject);
var
fs:TFileStream;
ms:TMemoryStream;
c:TClass;
begin
try
c:= TClass.Create(self);
c.i:=1;
fs :=TFileStream.Create('c:\111.dat', fmCreate or fmOpenWrite);
ms :=TMemoryStream.Create;
ms.WriteComponent(c);
ms.Position:=0;
ObjectBinaryToText(ms, fs);
finally
ms.Free;
fs.Free;
end;
end;
end.
Вот так оно вроде бы работает. Я на кнопку вынес… c - тоже можешь освободить
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 21:03:57.053333
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: Angella [DCC Warning] Project1.dpr(18): W1036 Variable 'c' might not have been initialized При вызове процедруры локальные переменные принимают случайные значения, оставшиеся на стеке от предыдущих вызовов. Соответственно, их надо инициализировать. В твоём случае инициализации не было никакой, поэтому переменная-указатель c указывала просто на какой-то случайый кусок памяти. Объект в Делфи всегда создаётся в оперативной памяти, то есть просто так к указателю обратиться нельзя, нужно сначала вызвать конструктор для объекта. Как показала практика, можно в качестве аргумента в конструктор передать просто nil.
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 21:39:03.290000
|
|
|
Angella
Сообщений: 22
Оценки: 0
Присоединился: 2007-08-02 23:45:39.443333
|
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
type
TClass = class(TComponent)
public
i:integer;
s:string;
end;
var
fs:TFileStream;
ms:TMemoryStream;
c:TClass;
begin
c:=TClass.Create(nil);
c.i:=1;
c.s:='asd';
fs :=TFileStream.Create('111.dat', fmCreate or fmOpenWrite);
ms :=TMemoryStream.Create;
ms.WriteComponent(c);
ms.Position:=0;
ObjectBinaryToText(ms, fs);
ms.Free;
fs.Free;
end.
сделал так, вроде что-то записал в файл. значит вся проблема была в том, что надо было создать объект класса TClass, а c:TClass просто создает ссылку. я до этого в шарпе работал, там естессно я знал, что такое new :) а тут видимо сработал рефлекс из процедурного Pascal'я. Спасибо большое alexbozhko и kreol за помощь. а что означает self при создании объекта? у меня ругается. Это связано с наследованием?
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 22:12:58.856666
|
|
|
Angella
Сообщений: 22
Оценки: 0
Присоединился: 2007-08-02 23:45:39.443333
|
Чувствую себя полным идиотом 0_о Записал объект в файл тхт. открыл блокнотом. Содержимое файла: object TClass end есть подозрение, довольно серьезное, что переменные i и s не записались :( решил прочитать содержимое файла:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Windows;
type
TClass = class(TComponent)
public
i:integer;
s:string;
end;
var
fs:TFileStream;
fsRead:TFileStream;
ms:TMemoryStream;
msRead:TMemoryStream;
c:TClass;
cRead:TClass;
begin
c:=TClass.Create(nil);
c.i:=1;
c.s:='asd';
fs :=TFileStream.Create('111.dat, fmCreate or fmOpenWrite);
ms :=TMemoryStream.Create;
ms.WriteComponent(c);
ms.Position:=0;
ObjectBinaryToText(ms, fs);
fsRead :=TFileStream.Create('111.dat', fmOpenRead);
msRead.Create;
cRead:=TClass.Create(nil);
ObjectTextToBinary(fsRead, msRead);
msRead.Position:=0;
msRead.ReadComponent(cRead);
WriteLn(cRead.i, ' ', cRead.s);
ReadLn;
ms.Free;
fs.Free;
msRead.Free;
fsRead.Free;
end.
выдает исключение на строку msRead.Position:=0; Exception class EAccessViolation with message 'Access violation at address 00404563 in module Project1.exe' мое неопытное предположение, что не может прочитать значения, которые не были записаны в файл. но если это так(естессно это не так), то почему ругается на Position:=0 пытался записать в тхт и прочитать оттуда же. такое же пишет.
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 22:16:56.193333
|
|
|
alexbozhko
Сообщений: 1024
Оценки: 0
Присоединился: 2005-11-24 13:35:34
|
quote:
ORIGINAL: Angella сделал так, вроде что-то записал в файл. значит вся проблема была в том, что надо было создать объект класса TClass, а c:TClass просто создает ссылку. я до этого в шарпе работал, там естессно я знал, что такое new :) а тут видимо сработал рефлекс из процедурного Pascal'я. Спасибо большое alexbozhko и kreol за помощь. Но вот интересно, kreol. ты объявил переменные ms, fs и c в событии Button1Click, разве они не будут локальными для этого события? и что означает self при создании объекта? у меня ругается. Это связано с наследованием? Будут локальными. Можешь вынести описания классов куда-нибудь еще Но смысла не вижу self в данном случае - Form6 В консольном приложении можно nil поставить (да и не в консольном - тоже)
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-26 22:24:12.023333
|
|
|
Angella
Сообщений: 22
Оценки: 0
Присоединился: 2007-08-02 23:45:39.443333
|
Да я уже понял, что сморозил на счет локальности, и удалил этот вопрос! ибо не учел, что дальнейший блок begin end относится к этому событию :) просто непривычно чуть-чуть в этом синтаксисе.
|
|
|
RE: как сохранить объект в файл? delphi - 2009-10-27 00:09:52.343333
|
|
|
Angella
Сообщений: 22
Оценки: 0
Присоединился: 2007-08-02 23:45:39.443333
|
Вычитал в инете: при сериализации объекта в поток сохраняется и может быть восстановлена та и только та информация, которая либо содержится в read/write published-свойствах объекта, либо способ записи и чтения которой определён в псевдосвойствах.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TClass = class(TComponent)
private
i:integer;
s:string;
published
property propertyI:integer read i write i;
property propertyS:String read s write s;
end;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
c:TClass;
cc:TClass;
fs:TFileStream;
ms:TMemoryStream;
msRead:TMemoryStream;
begin
c:=TClass.Create(self);
c.i:=1;
c.s:='asd';
fs :=TFileStream.Create('123.txt', fmCreate or fmOpenWrite);
ms :=TMemoryStream.Create;
ms.WriteComponent(c);
ms.Position:=0;
ObjectBinaryToText(ms, fs);
ms.Free;
fs.Free;
fs :=TFileStream.Create('123.txt', fmOpenRead);
msRead :=TMemoryStream.Create;
ObjectTextToBinary(fs, ms);
msRead.Position:=0;
cc:=TClass.Create(self);
msRead.ReadComponent(cc);
label1.Caption := cc.s + ' ' + IntToStr(cc.i);
end;
end.
содержимое тхт файла: object TClass propertyI = 1 propertyS = 'asd' end label1.caption = 'asd 1' получилось :) еще раз спасибо вам :)
|
|
|
|
|