Форум: "Начинающим";
Текущий архив: 2008.02.03;
Скачать: [xml.tar.bz2];
ВнизСохранение динамического массива в файл Найти похожие ветки
← →
Mixail (2008-01-10 15:06) [0]Не подскажете ли, как сохранить в файл динамический массив, который является свойством объекта Record? Попытался с функцией SetLength(), но после сохранения и обратной загрузки данных из файла выводятся пустые строки.
← →
Евгений Р. (2008-01-10 15:13) [1]f:file;
n:integer;
n:=размер заполненной части массива
BlockWrite(f,n,1);
← →
Palladin © (2008-01-10 15:15) [2]
> Не подскажете ли, как сохранить в файл динамический массив,
> который является свойством объекта Record?
в типизированный файл - никак
← →
Mixail (2008-01-10 15:16) [3]Спасибо за совет, Евгений Р.
Попробую ваш вариант. Я применял TFileStream, но не получалось.
← →
Джо © (2008-01-10 15:20) [4]Приведите объявление массива.
← →
clickmaker © (2008-01-10 15:23) [5]"динамический массив" и "пустые строки" - это массив из String, что-ли?
← →
Palladin © (2008-01-10 15:26) [6]
> [1] Евгений Р. (10.01.08 15:13)
ню ню...
> [3] Mixail (10.01.08 15:16)
ну у тебя ошибка в 17 строке...Type
TMyRec=Record
a:Array of Integer;
b:Array of Byte;
End;
Procedure SaveRec(fs:TFileStream;r:TMyRec);
Var
n:Integer;
Begin
n:=Length(r.a);
fs.Write(n,SizeOf(n)*SizeOf(Integer));
fs.Write(r.a[0],n*SizeOf(Integer));
n:=Length(r.b);
fs.Write(n,SizeOf(n));
fs.Write(r.b[0],n);
End;
Procedure ReadRec(fs:TFileStream;Var r:TMyRec);
Var
n:Integer;
Begin
fs.Read(n,SizeOf(n));
SetLength(r.a,n);
fs.Read(r.a[0],n*SizeOf(Integer));
fs.Read(n,SizeOf(n));
SetLength(r.b,n);
fs.Read(r.b[0],n);
End;
чего сложного то?
← →
Mixail (2008-01-10 15:28) [7]clickmaker, ни строки, ни цифры не сохраняются. При переводе того же массива на статический, данные сохраняются.
← →
Palladin © (2008-01-10 15:30) [8]ошибся при записи... пусть будет заданием на дом...
← →
Плохиш © (2008-01-10 15:32) [9]
> Mixail (10.01.08 15:28) [7]
Сказали же уже "ошибка в 17й строке"
← →
Mixail (2008-01-10 15:41) [10]"ошибка в 17й строке" кода своего автора, а я не указывал свой код
← →
Сергей М. © (2008-01-10 15:41) [11]
> При переводе того же массива на статический, данные сохраняются
Это означает только одно - ты не понимаешь разницы между статическим и динамическим массивами.
← →
Сергей М. © (2008-01-10 15:43) [12]
> Mixail (10.01.08 15:41) [10]
> я не указывал свой код
Ну и продолжай париться.
← →
Mixail (2008-01-10 15:52) [13]Сергей М., по-моему ты перепутал этот форум с развлекательными. Никто не нуждается в оценке "потенциала понимания". Мне действительно нужен совет по применению динамического массива внутри объекта Record, и сохранению его в файл через TFileStream.
← →
Palladin © (2008-01-10 15:54) [14]:) чукча не читатель, чукча писатель
← →
Сергей М. © (2008-01-10 15:55) [15]
> Mixail (10.01.08 15:52) [13]
> ты перепутал
Угу.
Который уже год путаю.
> применению динамического массива внутри объекта Record
Ничто не мешает этому применению.
Обычным образом оно осуществляется.
> и сохранению его в файл
см. [11]
Как только поймешь, так и вопросы сами по себе отпадут.
← →
Сергей М. © (2008-01-10 15:56) [16]
> Mixail (10.01.08 15:52) [13]
Тебе, чукче, уже в [6] дали тот самый вожделенный совет)
← →
Юрий Зотов © (2008-01-10 16:17) [17]> Mixail
Запись файла:
1. Пишем в файл целое число длиной 4 байта (кол-во эл-тов в массиве)
2. Пишем сами элементы.
Чтение файла:
1. Читаем 4 байта в целую переменную.
2. Устанавливаем длину массива.
3. Читаем элементы массива.
← →
Mixail (2008-01-10 16:24) [18]Юрий, имеешь ввиду целое число внутри Record? И как связать это целое число с самими элементами? Прошу совета.
← →
@!!ex © (2008-01-10 16:38) [19]> [18] Mixail (10.01.08 16:24)
Че за идиотизм?? Ответили уже раз десять...
Уважаемый, послушайте Сергея, он вам дело говорит, учите матчасть, и втыкайте в различия между статическим и динамическим массивом...
type
MyRec=record
T:array of Items;
Count:integer;
end;
var
Index:integer;
begin
Write(Count);
for Index:=0 to Count-1 do
Write(T[Index]);
end;
← →
Palladin © (2008-01-10 16:41) [20]
> [19] @!!ex © (10.01.08 16:38)
а count то на кой? [6] смотрел?
← →
Плохиш © (2008-01-10 16:46) [21]
> Palladin © (10.01.08 16:41) [20]
Так ведь "Чем дальше в лес, тем толще партизаны" :-))
← →
Юрий Зотов © (2008-01-10 16:50) [22]> Mixail (10.01.08 16:24) [18]
> целое число внутри Record?
Нет. Никакие Record тут вообще ни при чем. Есть массив, который надо записать в файл. И без разницы, где этот массив находится - в Record или нет. Сначала пишем в файл длину массива (4 байта), потом сам массив.
То же самое при чтении. Есть файл, который надо прочитать в массив. И снова без разницы, где этот массив находится - в Record или нет. Сначала читаем из файла 4 байта, потом устанавливаем длину массива, потом читаем сам массив.
Есть одно "но" - если это массив длинных строк, то каждую строку надо писать (и читать) по той же схеме - сначала длину строки (4 байта), потом тело строки.
> @!!ex © (10.01.08 16:38) [19]
Поле Count внутри MyRec - лишнее.
← →
Сергей М. © (2008-01-10 17:02) [23]
> Mixail (10.01.08 16:24) [18]
Ты вообще соизволил проанализировать [6] ?
Или писатель ?)
← →
@!!ex © (2008-01-10 17:05) [24]> а count то на кой?
> Поле Count внутри MyRec - лишнее.
Это привычка... Часто приходится пользоваться данимаческими массивами вида: type TDynamycarray = array[0..0] of TItem;
Вот и забываю все время, что размер стандартного дин. массива можно узнать с помощью Length.
← →
Mixail (2008-01-11 16:28) [25]Обращаюсь истинным и щедрым мастерам Дельфи: уже несколько дней мучаюсь с динамическими массивами структуры (записи). Покопался во всей документации 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.
← →
Palladin © (2008-01-11 16:31) [26]
> [25] Mixail (11.01.08 16:28)
идентификатор динамического массива является ссылкой, на кой тебе ссылки в файле? тебе уже Сергей М. сколько раз намекнул поизучать, а ты так ничего и не понял! ты даже на мой код неудосужился глянуть. сразу бы понял что к чему. И ЮЗ тебе про то же твердит, а все в лоб да полбу...
← →
Mixail © (2008-01-11 16:35) [27]Palladin, твой код я не только просмотрел - и применил - строки не сохраняются. Используй shortstring или widestring вместо integer внутри record, потом проверь, работает ли.
← →
Palladin © (2008-01-11 16:37) [28]ты не путай теплое с мягким! нижний индекс дин массива = 0 нижний индекс строки 1
соответсвенно дабы мой код заработал и со строками нужно изменить a[0] на a[1]
← →
Сергей М. © (2008-01-11 16:37) [29]
> уже несколько дней мучаюсь
Канонизировать твой труп никто, думаю, не собирался.
← →
@!!ex © (2008-01-11 16:39) [30]> [25] Mixail (11.01.08 16:28)
Yo!! АЛЕ!!! НЕльзя днимаический фалй так сохранять!!!
Вы бы еще List так сохранили... или class...
Динамический массив нужно сохранять отдельно! либо поэлементно, либо как в [6](только надо понимать, что это работает, только если работаем с массивом элементарных структур, без указателей)
← →
Германн © (2008-01-11 16:40) [31]
> Есть одно "но" - если это массив длинных строк, то каждую
> строку надо писать (и читать) по той же схеме - сначала
> длину строки (4 байта), потом тело строки.
>
(c) Юрий Зотов © (10.01.08 16:50) [22]
И всё-таки ты чукча.
← →
Dennis I. Komarov © (2008-01-11 16:41) [32]> [25] Mixail (11.01.08 16:28)
Ну как вот тебе помочь, если ты сам себе не хочешь...
Что хранится в Rec.MyShotStr ?
← →
Dib@zol © (2008-01-11 16:42) [33]Вощем так. Слухай сюды.
Что такое статический массив? Это тот, который размещается в памяти заранее, сразу при старте проги. То есть, память под него заранее отведена. Так? Так. И записывается он в файл именно потому, что твой код читает побайтно етот кусок памяти и пишет его в файл.
А что мы имеем с массивом динамическим? Память под него выделяется по запросу программы, и может быть разного размера. Именно потому резевиовать память статически - нет смысла. А вдруг её окажется мало? А вдруг наоборот не хватит? Поэтому под динамический массив отводится всего четыре байта. Почему так мало, спросишь ты? Отвечаю: в ентих 4-х байтах записывается всего лишь адрес первого байта нашего массива. который физически расположен совершенно в другом куске памяти, нежели тот где ты его ищешь.
Вывод: кури хелп по динамическим массивам до полного просветления.
← →
Сергей М. © (2008-01-11 16:43) [34]
> просмотрел - и применил - строки не сохраняются.
Басурманин ?)
← →
Mixail © (2008-01-11 16:44) [35]Palladin, дело не в индексе, нижний индекс строки указал 0. Кроме того, если у меня 15 свойств в структуре, придется каждый читать и сохранить по-отдельности. Неужели невозможно поработать с длинами дин.массивов до чтения и сохранения, а в файл сохранить только саму структуру в целом.
← →
Palladin © (2008-01-11 16:47) [36]
> нижний индекс строки указал 0
Я тебе повторяю, нижний индекс строки 1 (один), мой пример для дин массивов, они с 0 (нуля)
> Кроме того, если у меня 15 свойств в структуре, придется
> каждый читать и сохранить по-отдельности. Неужели невозможно
> поработать с длинами дин.массивов до чтения и сохранения,
> а в файл сохранить только саму структуру в целом.
да, к сожалению (а ксожалению ли?) это так. Еслиб было все так просто, то и объекты классов было бы здорово сохранять. Почему нельзя сохранить одной операцией подробно разжевал [33] Dib@zol © (11.01.08 16:42)
← →
Palladin © (2008-01-11 16:48) [37]
> [35] Mixail © (11.01.08 16:44)
ну и соответственон еще раз повторюсь что бы пример заработал со строкой, нужно поменять в моем примере 0 на 1
← →
@!!ex © (2008-01-11 16:50) [38]> Еслиб было все так просто, то и объекты классов было бы
> здорово сохранять.
Поэтому есть сериализация, которую, кстати, можно было бы не плохо применить к этой записи, раз уж она такая большая...
Правда я ни разу не видел, чтобы сериализацию на дельфе делали, хотя может не туда смотрел...
← →
Palladin © (2008-01-11 16:52) [39]
> [38] @!!ex © (11.01.08 16:50)
вот тут сразу возникает вопрос, а нужен ли вообще Record, может Class таки сделать... заодно какой нибуть красивой функциональностью обрастить...
← →
Mixail © (2008-01-11 16:55) [40]Palladin, попытаюсь с "1". Если обратили внимание, я указал свойство "MyWideStr", а его тип назначил shortstring. Когда использовал массив из widestring даже внутри статического массива, при чтении из файла прога вызывает исключение. А применив массив из single, в результате получаю искаженные значение, обычно длинные значения после DecimalSeparator. Из-за чего, по-вашему?
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.02.03;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.045 c