Форум: "Основная";
Текущий архив: 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.03 c