Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сохранение динамического массива в файл [D7]


Страницы:   1 2 3 4

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 - лишнее.


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо