Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.25;
Скачать: CL | DM;

Вниз

Запись в файл   Найти похожие ветки 

 
Comp ©   (2004-02-13 11:17) [0]

Ребята, как можно записать в файл запись, которая, помимо других полей, будет содержать поле типа динамического массива, т.е. в разных случаях записи число элементов этого массива должно быть различным.
Выдается ошибка - "требуется финализация...". Как ее избежать?

К примеру - вместо этого динамического массива допустим надо записать BitMap произвольного размера...


 
Maxud ©   (2004-02-13 11:27) [1]

Если вынести Bitmap из рекорда, то так, кажись, можно:
FileStream.Write(MyRec, SizeOf(MyRec));
Bitmap.SaveToStream(FileStream);

Ну и читать в обратной последовательности.


 
Fiend ©   (2004-02-13 11:32) [2]

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


 
Тимохов ©   (2004-02-13 11:35) [3]


> Comp © (13.02.04 11:17)

Если хочется записать динамический массив, то это надо делать ручками и явно.
Ответ [1] для динамических массивов неприемлем.
Т.е.
1. надо записать все числовые поля из рекорда явно.
2. надо записать длину динамического массива, а потом записать тело массива. Если же массив строк. то нужно явно записать каждую строку.
3. все строковые поля нужно также записывать явно.

Читать в обратном порядке.


 
PVOzerski ©   (2004-02-13 11:35) [4]

Можно и без стримов, но придется работать с нетипизированным файлом через blockread/blockwrite, причем в блоки писать/читать не преременную-дин. массив, а как бы его начальный элемент, только длину блока задавать на всю длину массива (с учетом длины элементов, естественно).


 
Comp ©   (2004-02-13 11:38) [5]

Неплохая идея. Спасибо.


 
Maxud ©   (2004-02-13 11:40) [6]


> Тимохов © (13.02.04 11:35) [3]


> Ответ [1] для динамических массивов неприемлем

Имелось ввиду:

> К примеру - вместо этого динамического массива допустим
> надо записать BitMap произвольного размера...


 
Comp ©   (2004-02-13 11:40) [7]

Спасибо всем.


 
olookin ©   (2004-02-13 11:44) [8]

[3] Тимохов © (13.02.04 11:35)

> Comp © (13.02.04 11:17)

Если хочется записать динамический массив, то это надо делать ручками и явно.
Ответ [1] для динамических массивов неприемлем.

Не совсем так. Например записать весь массив разом можно так:

procedure TForm1.Button1Click(Sender: TObject);
var f: tfilestream;
x: array of double;
begin
SetLength(x,1000); x[9]:=547654;
f:=tfilestream.create("E:\111.xxx",fmCreate);
f.Write(x[0],Length(x)*sizeof(double));
f.free;
end;

И читать разом так:
procedure TForm1.Button2Click(Sender: TObject);
var f: tfilestream;
x: array of double;
begin
SetLength(x,1000);
f:=tfilestream.create("E:\111.xxx",fmopenread);
f.read(x[0],Length(x)*sizeof(double));
f.free;
showmessage(floattostr(x[9]));
end;

Поспешили следовательно с выводами. Другое дело, что тут явно задана длина массива. Т.е. либо заранее известна длина, либо ее тоже записать в файл перед массивом...


 
Comp ©   (2004-02-13 11:49) [9]

> olookin ©

Спасибо. Я попробую.


 
Тимохов ©   (2004-02-13 11:49) [10]


> Поспешили следовательно с выводами.

Ну я это и имел в виду под "ручками". Автор же спрашивал можно ли всю запись разом записать. Ответ, нельзя - надо ручками, т.е. как у вас. Т.е. никуда мы не спешили.
Строки (длинные) вы так не запишете.


 
Mystic ©   (2004-02-13 12:00) [11]

1) Порождаешь класс от TPersistent или от TCollection. Используешь для записи в поток методы

unit Stdio;

interface

uses
Classes;

procedure WritePersistent(S: TStream; Instance: TPersistent);
procedure ReadPersistent(S: TStream; Instance: TPersistent);

procedure WriteCollection(S: TStream; Instance: TCollection);
procedure ReadCollection(S: TStream; Instance: TCollection);

implementation

type
TMyWriter = class(TWriter)
public
procedure
MyWriteCollection(Instance: TCollection);
procedure WritePersistent(Instance: TPersistent);
end;

procedure TMyWriter.MyWriteCollection(Instance: TCollection);
begin
WriteCollection(Instance);
end;

procedure TMyWriter.WritePersistent(Instance: TPersistent);
begin
WriteProperties(Instance);
WriteListEnd;
end;

type
TMyReader = class(TReader)
public
procedure
MyReadCollection(Instance: TCollection);
procedure ReadPersistent(Instance: TPersistent);
end;

procedure TMyReader.MyReadCollection(Instance: TCollection);
var
Value: TValueType;
begin
Value := ReadValue;
if Value <> vaCollection then
raise
EStreamError.Create("vaCollection excepted");
ReadCollection(Instance);
end;

procedure TMyReader.ReadPersistent(Instance: TPersistent);
begin
while not
EndOfList do ReadProperty(Instance);
ReadListEnd;
end;

procedure WriteCollection(S: TStream; Instance: TCollection);
var
Writer: TMyWriter;
begin
Writer := TMyWriter.Create(S, 4096);
try
Writer.MyWriteCollection(Instance);
finally
Writer.Free;
end;
end;

procedure ReadCollection(S: TStream; Instance: TCollection);
var
Reader: TMyReader;
begin
Reader := TMyReader.Create(S, 4096);
try
Reader.MyReadCollection(Instance);
finally
Reader.Free;
end;
end;

procedure WritePersistent(S: TStream; Instance: TPersistent);
var
Writer: TMyWriter;
begin
Writer := TMyWriter.Create(S, 4096);
try
Writer.WritePersistent(Instance);
finally
Writer.Free;
end;
end;

procedure ReadPersistent(S: TStream; Instance: TPersistent);
var
Reader: TMyReader;
begin
Reader := TMyReader.Create(S, 4096);
try
Reader.ReadPersistent(Instance);
finally
Reader.Free;
end;
end;

end.


2) Реализовывать запись вручную.


 
olookin ©   (2004-02-13 12:03) [12]

[10] Тимохов © (13.02.04 11:49)

> Поспешили следовательно с выводами.

Ну значит я поспешил. Впрочем меня смутило это:

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

Чего тогда тут имелось в виду?


 
Тимохов ©   (2004-02-13 12:06) [13]


> olookin © (13.02.04 12:03) [12]

f.write(rec.field1, sizeof(rec.field1));
f.write(rec.field2, sizeof(rec.field2));
и т.д.
запись дин массивов (как у вас)
запись строк

можно конечно записать одной командой, если поля идут подряд и рекорд packed. Но ИМХО с несколькоими командами нагладнее.



Страницы: 1 вся ветка

Текущий архив: 2004.02.25;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.525 c
1-79724
smolin
2004-02-12 11:21
2004.02.25
Функция перемещения файла


1-79937
Leech
2004-02-09 16:52
2004.02.25
Открыть существующий документ в приложении Microsoft Word...


14-80154
Rule
2004-02-01 22:58
2004.02.25
ПОЧЕМУ У МЕНЯ НЕТ КОМПОНЕНТЫ TIBSCRIPT ???????


6-80085
Cure
2003-12-04 23:11
2004.02.25
Звук по локалке


4-80352
Ivan K.
2003-12-18 07:43
2004.02.25
Как получить названия окон?