![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сохранение динамического массива в файл [D7]
Mixail © (2008-01-10 15:06:00)Не подскажете ли, как сохранить в файл динамический массив, который является свойством объекта Record? Попытался с функцией SetLength(), но после сохранения и обратной загрузки данных из файла выводятся пустые строки.
Palladin (2008-01-11 18:34:00) [1]понятно, прикольно, через попу :)
статья да, будет полезна
Sapersky (2008-01-11 18:27:00) [2]It's a kind of magic :)
Натурально, compiler magic. Т.е. работает по тому же принципу (и использует то же TypeInfo), что и magic-функции из system.pas (_InitializeArray/_FinalizeArray и т.п).
Всё никак не соберусь написать статью на эту тему, но пример, в принципе, есть, могу выложить.
Dib@zol (2008-01-11 18:15:00) [3]Разыменование? =)
> гы ^)
Именно :)
Palladin (2008-01-11 18:12:00) [4]гы ^) и какой же позвольте узнать? :)
Sapersky (2008-01-11 18:11:00) [5]> Кроме того, если у меня 15 свойств в структуре, придется
> каждый читать и сохранить по-отдельности. Неужели невозможно
> поработать с длинами дин.массивов до чтения и сохранения,
> а в файл сохранить только саму структуру в целом.
да, к сожалению (а ксожалению ли?) это так. Еслиб было все так просто, то и объекты классов было бы здорово сохранять.
Есть на самом деле один хакерский трюк, который позволяет скидывать в файл подобные рекорды "одним изящным движением". Для классов, правда, подходит слабо, т.к. вложенные не видит.
Mixail (2008-01-11 18:06:00) [6]Выхожу, поэтому благодарю всех, кто уделил время на мою проблему и попытался помочь.
Германн (2008-01-11 17:55:00) [7]
> Palladin © (11.01.08 17:46) [54]
>
>
А точно. Что запишет, то и прочитает.
Palladin (2008-01-11 17:46:00) [8]
> [53] @!!ex © (11.01.08 17:41)
еще раз говорю: упакованность рекорда монопенисуальна при чтении/записи
@!!ex (2008-01-11 17:41:00) [9]> [52] Mixail © (11.01.08 17:37)
скорее проблема в неупакованном рекорде... о котором Сергей талдычит вот уже несколько постов.
Mixail (2008-01-11 17:37:00) [10]Испробовал все методы, наконец, по для экономичности вместо double решил исвользовать integer (умножив значение на 1000, а при чтении из файла разделив на 1000). Скорее проблема с записью single, т.к. значения я контролировал и до пересылки в структуру, и до записи в файл.
Palladin (2008-01-11 17:31:00) [11]
> [50] Германн © (11.01.08 17:26)
$A8, а что packed то даст?
Германн (2008-01-11 17:26:00) [12]
> Palladin © (11.01.08 17:19) [47]
>
>
А разве по умолчанию не $A8 ?
Palladin (2008-01-11 17:25:00) [13]
> А single действительно из файла возвращают искаженные цифры.
такого просто не может быть... проверь таким образом
и до записи и после чтения выведи в Memo
For i:=0 to 9 do memo1.lines.add(Inttostr(Integer(Rec.SingleNm[i]));
если целочисленные значения не будут одинаковыми, то у тебя проблеммы или с записью или с чтением или и с тем и другим
Mixail (2008-01-11 17:22:00) [14]Palladin, благодарю. Попробую твой код. А single действительно из файла возвращают искаженные цифры. Double работает нормально.
Palladin (2008-01-11 17:19:00) [15]
> [46] Сергей М. © (11.01.08 17:17)
а зачем? размер всех элементов 4 байта (в приведенном примере)
Сергей М. (2008-01-11 17:17:00) [16]
> Mixail © (11.01.08 17:14) [45]
Михуил, изволь использовать packed.
Будет приятно)
Mixail (2008-01-11 17:14:00) [17]Сергей М., чего приятного тебе от дурных и бескультурных выражений, у тебя тоже наступит возраст как у меня, будет не сладко когда пацаны будут дурно тебе выражаться.
Palladin (2008-01-11 17:10:00) [18]ну ты молодец конечно, singl'ы должны сохранится как есть, а вот с WideStr проблемка, WideStr:array [0..9] of widestring есть 10 элемеyтов указателей, вот ты эти указатели и сохраняешь, тут не прокатит так просто
надо так
var
n:Integer;
fs:=TFileStream.Create('MyRec.dat', fmCreate);
fs.Write(Rec.SingleNm,SizeOf(Rec.SingleNm));
for i:=0 to 9 Do
Begin
n:=Length(Rec.WideStr[i]);
fs.Write(n,SizeOf(n));
fs.Write(Rec.WideStr[i][1],n*2); // бо размер символа в WideStr 2 байта
End;
fs.Free;
соответственно код чтения
Var
n:Integer;
fs.Read(Rec.SingleNm,SizeOf(Rec.SingleNm));
For i:=0 to 9 Do
Begin
fs.Read(n,SizeOf(n))l;
SetLength(Rec.WideStr[i],n);
fs.Read(Rec.WideStr[i][1],n*2);
End;
Сергей М. (2008-01-11 17:05:00) [19]
> Mixail © (11.01.08 17:00) [42]
И в чем проблема, ув. Михуил ?
По случаю уж децл вопросов:
- где packedrecord ?
- какого ляда ты пользуешь Write вместо WriteBuffer ?
- как объявлен Rec ?
Mixail (2008-01-11 17:00:00) [20]Palladin, тот же самый код, со статическим массивом:
type
MyRecord = record
SingleNn: array [0..9] of single;
WideStr: array [0..9] of widestring;
end;
fs:=TFileStream.Create('MyRec.dat', fmCreate);
fs.Write(Rec,sizeof(Rec));
fs.Free;