Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.051 c
1-79867
Dr.Karter
2004-02-10 14:32
2004.02.25
Системное время


3-79629
geg
2004-02-02 11:23
2004.02.25
Перенос данных между таблицами


1-79846
Тимохов
2004-02-10 17:21
2004.02.25
Delphi+WinApi II


1-79851
snake1977
2004-02-10 16:55
2004.02.25
преобразовать строку


3-79661
SasaR
2004-01-30 11:41
2004.02.25
InterBase :(





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский