![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сохранение динамического массива в файл [D7]
Mixail © (2008-01-10 15:06:00)Не подскажете ли, как сохранить в файл динамический массив, который является свойством объекта Record? Попытался с функцией SetLength(), но после сохранения и обратной загрузки данных из файла выводятся пустые строки.
Palladin (2008-01-11 16:56:00) [21]
> [40] Mixail © (11.01.08 16:55)
> Когда использовал массив из widestring даже внутри статического
> массива, при чтении из файла прога вызывает исключение
> А применив массив из single, в результате получаю искаженные
> значение, обычно длинные значения после DecimalSeparator.
кусочек кода записи/чтения покажи, так никто тебе не скажем в чем ошибка
Mixail (2008-01-11 16:55:00) [22]Palladin, попытаюсь с "1". Если обратили внимание, я указал свойство "MyWideStr", а его тип назначил shortstring. Когда использовал массив из widestring даже внутри статического массива, при чтении из файла прога вызывает исключение. А применив массив из single, в результате получаю искаженные значение, обычно длинные значения после DecimalSeparator. Из-за чего, по-вашему?
Palladin (2008-01-11 16:52:00) [23]
> [38] @!!ex © (11.01.08 16:50)
вот тут сразу возникает вопрос, а нужен ли вообще Record, может Class таки сделать... заодно какой нибуть красивой функциональностью обрастить...
@!!ex (2008-01-11 16:50:00) [24]> Еслиб было все так просто, то и объекты классов было бы
> здорово сохранять.
Поэтому есть сериализация, которую, кстати, можно было бы не плохо применить к этой записи, раз уж она такая большая...
Правда я ни разу не видел, чтобы сериализацию на дельфе делали, хотя может не туда смотрел...
Palladin (2008-01-11 16:48:00) [25]
> [35] Mixail © (11.01.08 16:44)
ну и соответственон еще раз повторюсь что бы пример заработал со строкой, нужно поменять в моем примере 0 на 1
Palladin (2008-01-11 16:47:00) [26]
> нижний индекс строки указал 0
Я тебе повторяю, нижний индекс строки 1 (один), мой пример для дин массивов, они с 0 (нуля)
> Кроме того, если у меня 15 свойств в структуре, придется
> каждый читать и сохранить по-отдельности. Неужели невозможно
> поработать с длинами дин.массивов до чтения и сохранения,
> а в файл сохранить только саму структуру в целом.
да, к сожалению (а ксожалению ли?) это так. Еслиб было все так просто, то и объекты классов было бы здорово сохранять. Почему нельзя сохранить одной операцией подробно разжевал [33] Dib@zol © (11.01.08 16:42)
Mixail (2008-01-11 16:44:00) [27]Palladin, дело не в индексе, нижний индекс строки указал 0. Кроме того, если у меня 15 свойств в структуре, придется каждый читать и сохранить по-отдельности. Неужели невозможно поработать с длинами дин.массивов до чтения и сохранения, а в файл сохранить только саму структуру в целом.
Сергей М. (2008-01-11 16:43:00) [28]
> просмотрел - и применил - строки не сохраняются.
Басурманин ?)
Dib@zol (2008-01-11 16:42:00) [29]Вощем так. Слухай сюды.
Что такое статический массив? Это тот, который размещается в памяти заранее, сразу при старте проги. То есть, память под него заранее отведена. Так? Так. И записывается он в файл именно потому, что твой код читает побайтно етот кусок памяти и пишет его в файл.
А что мы имеем с массивом динамическим? Память под него выделяется по запросу программы, и может быть разного размера. Именно потому резевиовать память статически - нет смысла. А вдруг её окажется мало? А вдруг наоборот не хватит? Поэтому под динамический массив отводится всего четыре байта. Почему так мало, спросишь ты? Отвечаю: в ентих 4-х байтах записывается всего лишь адреспервого байта нашего массива. который физически расположен совершенно в другом куске памяти, нежели тот где ты его ищешь.
Вывод: кури хелп по динамическим массивам до полного просветления.
Dennis I. Komarov (2008-01-11 16:41:00) [30]> [25] Mixail (11.01.08 16:28)
Ну как вот тебе помочь, если ты сам себе не хочешь...
Что хранится в Rec.MyShotStr ?
Германн (2008-01-11 16:40:00) [31]
> Есть одно "но" - если это массив длинных строк, то каждую
> строку надо писать (и читать) по той же схеме - сначала
> длину строки (4 байта), потом тело строки.
>
(c) Юрий Зотов © (10.01.08 16:50) [22]
И всё-таки ты чукча.
@!!ex (2008-01-11 16:39:00) [32]> [25] Mixail (11.01.08 16:28)
Yo!! АЛЕ!!! НЕльзя днимаический фалй так сохранять!!!
Вы бы еще List так сохранили... или class...
Динамический массив нужно сохранять отдельно! либо поэлементно, либо как в [6](только надо понимать, что это работает, только если работаем с массивом элементарных структур, без указателей)
Сергей М. (2008-01-11 16:37:00) [33]
> уже несколько дней мучаюсь
Канонизировать твой труп никто, думаю, не собирался.
Palladin (2008-01-11 16:37:00) [34]ты не путай теплое с мягким! нижний индекс дин массива = 0 нижний индекс строки 1
соответсвенно дабы мой код заработал и со строками нужно изменить a[0] на a[1]
Mixail (2008-01-11 16:35:00) [35]Palladin, твой код я не только просмотрел - и применил - строки не сохраняются. Используй shortstring или widestring вместо integer внутри record, потом проверь, работает ли.
Palladin (2008-01-11 16:31:00) [36]
> [25] Mixail (11.01.08 16:28)
идентификатор динамического массива является ссылкой, на кой тебе ссылки в файле? тебе уже Сергей М. сколько раз намекнул поизучать, а ты так ничего и не понял! ты даже на мой код неудосужился глянуть. сразу бы понял что к чему. И ЮЗ тебе про то же твердит, а все в лоб да полбу...
Mixail (2008-01-11 16:28:00) [37]Обращаюсь истинным и щедрым мастерам Дельфи: уже несколько дней мучаюсь с динамическими массивами структуры (записи). Покопался во всей документации Borland, ничего не вышло – структура с динамическими массивами не сохраняется в файл. Вчера ребята посоветовали пару вариантов, но и это не помогло. Дело в том, что проблема не с объявлением длины массива – хоть сохрани значение длины массива в самом файле, хоть объяви константой – не работает, точнее исключений не вызывает, но данные не сохраняются в файле. Нужно в файле сохранить структуру в целом (fs.Read(Rec, sizeof(Rec))), а не каждое свойство по отдельности, так как таких свойств у моей струтуры масса. Один ньюанс – как только переводишь динамический массив на статический и убираешь функции SetLength(), структура сохраняется, словно это не тот самый код.
Прошу мастеров, подправьте, пожалуйста, код ниже – я его максимально сократил, оставил две процедуры, работающие с двумя свойствами структуры и двумя компонентами TMemo. Буду искренне благодарен за помощь. michail_col@yahoo.com
type
MyRecord = record
MyShortStr: array of shortstring; // первое свойство
//... // второе и последующие свойства
MyWideStr: array of shortstring; // последнее свойство
end;
...
var
Form1: TForm1;
Rec: MyRecord;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
var
fs: TFileStream;
n: integer;
begin
SetLength(Rec.MyShortStr,3);
SetLength(Rec.MyWideStr,3);
if FileExists('MyRec.dat') then begin
fs:=TFileStream.Create('MyRec.dat', fmOpenRead);
fs.Read(Rec, sizeof(Rec));
fs.Free;
for n:=0 to 2 do Memo1.Lines.Add(Rec.MyShortStr[n]);
for n:=0 to 2 do Memo2.Lines.Add(Rec.MyWideStr[n]);
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
fs:TFileStream;
n: integer;
begin
for n:=0 to 2 do Rec.MyShortStr[n]:= Memo1.Lines.Strings[n];
for n:=0 to 2 do Rec.MyWideStr[n]:= Memo2.Lines.Strings[n];
fs:=TFileStream.Create('MyRec.dat', fmCreate);
fs.Write(Rec,sizeof(Rec));
fs.Free;
end;
end.
@!!ex (2008-01-10 17:05:00) [38]> а count то на кой?
> Поле Count внутри MyRec - лишнее.
Это привычка... Часто приходится пользоваться данимаческими массивами вида: type TDynamycarray = array[0..0] of TItem;
Вот и забываю все время, что размер стандартного дин. массива можно узнать с помощью Length.
Сергей М. (2008-01-10 17:02:00) [39]
> Mixail (10.01.08 16:24) [18]
Ты вообще соизволил проанализировать [6] ?
Или писатель ?)
Юрий Зотов (2008-01-10 16:50:00) [40]> Mixail (10.01.08 16:24) [18]
> целое число внутри Record?
Нет. Никакие Record тут вообще ни при чем. Есть массив, который надо записать в файл. И без разницы, где этот массив находится - в Record или нет. Сначала пишем в файл длину массива (4 байта), потом сам массив.
То же самое при чтении. Есть файл, который надо прочитать в массив. И снова без разницы, где этот массив находится - в Record или нет. Сначала читаем из файла 4 байта, потом устанавливаем длину массива, потом читаем сам массив.
Есть одно "но" - если это массив длинных строк, то каждую строку надо писать (и читать) по той же схеме - сначала длину строки (4 байта), потом тело строки.
> @!!ex © (10.01.08 16:38) [19]
Поле Count внутри MyRec - лишнее.