Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.10.20;
Скачать: CL | DM;

Вниз

Как сохранить в файл и загрузить из файла безразмерный массив   Найти похожие ветки 

 
Sergp ©   (2003-10-07 13:32) [0]

Сабж.
При загрузке размер массива неизвестен. Как сохранить массив в файл вместе с информацией о размерности, а потом загрузить его оттуда, чтобы размерность массива установилась такой, какой была при сохранении?


 
Hooch ©   (2003-10-07 13:38) [1]

сохранить сначала размер, потом сам массив.


 
Skier ©   (2003-10-07 13:39) [2]

>Sergp © (07.10.03 13:32)
Сохранение :
-сохранить размер
-сохранить массив
Чтение
-считать длину массива
-читать массив


 
Palladin ©   (2003-10-07 13:39) [3]

а вообще опыт записи/чтения в/из файл(а) имеешь?


 
han_malign ©   (2003-10-07 13:39) [4]

>в файл вместе с информацией о размерности


 
Hooch ©   (2003-10-07 13:41) [5]

т.е. например создать FileStream сначала записать размер
Length(Array), SizeOf(Integer)) потом сам массив либо по элементам либо сразу весь блок


 
Digitman ©   (2003-10-07 13:41) [6]

разве ты не в состоянии прочитать элементы инф-ции о размерностях массива в переменную ?
а затем, перед сохранением собственно данных массива, записать в файл значения этих переменных ?
с тем чтобы при чтении из файла установить размерности массива соотв.образом, перед тем как считывать в массив следом идущие в файле собственно данные ?

есть же ф-ции TVarData, VarArrayDimCount(), VarArrayLow/HighBound() и пр. !
они позволят получить инф-цию о структуре массива, с тем чтобы сохранив/прочитав ее можно было бы восстановить структуру воссоздаваемого массива банальным вызовом VarArrayCreate()


 
Sergp ©   (2003-10-07 14:12) [7]


> Digitman © (07.10.03 13:41) [6]
> разве ты не в состоянии прочитать элементы инф-ции о размерностях
> массива в переменную ?
> а затем, перед сохранением собственно данных массива, записать
> в файл значения этих переменных ?


В состоянии. Но я думал что есть более простой способ, и считал что так как я думаю сделать было бы по-ламерски.


 
Palladin ©   (2003-10-07 14:17) [8]

никогда так не думай... если есть варианты приводящие к нужному результату, то при чем сдесь "ламерство"...
реализуй так как ты думаешь, позже может быть ты найдешь другое решение, это и есть развитие...


 
Sergp ©   (2003-10-07 16:33) [9]

Все-таки решил попытаться отдельно не сохранять в файле переменную с кол. записей. Написал вот это нечто, но оно не работает. Не могу понять в чем дело.

...
type
InfoNode=record
parent:integer;
fileNum:cardinal;
text:string[120];
end;
...

NodeList:array of InfoNode;
...

// Сохранение списка узлов в массив, а затем в файл
procedure TForm1.NodeSave;
var
f:file;
i,k:integer;
begin
k:=TreeView1.Items.Count;
SetLength(nodelist,k); // в примере число узлов - 11
for i:=0 to k-1 do
begin
with Treeview1.items.Item[i] do
begin
if parent=nil then nodelist[i].Parent:=99999999 else
nodelist[i].parent:=parent.absoluteindex;
nodelist[i].text:=text;
nodelist[i].fileNum:=cardinal(data);
end;
end;
RichEdit1.lines.add(inttostr(sizeof(nodelist))); //Здесь мы видим 4
RichEdit1.lines.add(inttostr(TreeView1.items.count)); //хотя здесь 11

assignfile(f,"nodelist.dat");
rewrite(f,128);
blockwrite(f,nodelist,k);
closefile(f);
end;

// Загрузка из файла
procedure TForm1.NodeLoad;
var
f:file;
begin
assignfile(f,"nodelist.dat");
reset(f,128);
SetLength(nodelist,FileSize(f));
blockread(f,nodelist,Filesize(f));
RichEdit1.lines.add(inttostr(filesize(f))); //Здесь видим 11
closefile(f);
RichEdit1.lines.add(nodelist[2].text); //А здесь пусто хотя у узла в text что-то было.
end;


 
Sergp ©   (2003-10-07 16:35) [10]

Все-таки решил попытаться отдельно не сохранять в файле переменную с кол. записей. Написал вот это нечто, но оно не работает. Не могу понять в чем дело.

...
type
InfoNode=record
parent:integer;
fileNum:cardinal;
text:string[120];
end;
...

NodeList:array of InfoNode;
...

// Сохранение списка узлов в массив, а затем в файл
procedure TForm1.NodeSave;
var
f:file;
i,k:integer;
begin
k:=TreeView1.Items.Count;
SetLength(nodelist,k); // в примере число узлов - 11
for i:=0 to k-1 do
begin
with Treeview1.items.Item[i] do
begin
if parent=nil then nodelist[i].Parent:=99999999 else
nodelist[i].parent:=parent.absoluteindex;
nodelist[i].text:=text;
nodelist[i].fileNum:=cardinal(data);
end;
end;
RichEdit1.lines.add(inttostr(sizeof(nodelist))); //Здесь мы видим 4
RichEdit1.lines.add(inttostr(TreeView1.items.count)); //хотя здесь 11

assignfile(f,"nodelist.dat");
rewrite(f,128);
blockwrite(f,nodelist,k);
closefile(f);
end;

// Загрузка из файла
procedure TForm1.NodeLoad;
var
f:file;
begin
assignfile(f,"nodelist.dat");
reset(f,128);
SetLength(nodelist,FileSize(f));
blockread(f,nodelist,Filesize(f));
RichEdit1.lines.add(inttostr(filesize(f))); //Здесь видим 11
closefile(f);
RichEdit1.lines.add(nodelist[2].text); //А здесь пусто хотя у узла в text что-то было.
end;


 
Skier ©   (2003-10-07 16:40) [11]

RichEdit1.lines.add(inttostr(sizeof(nodelist))); //Здесь мы видим 4

Разберись почему и многое станет ясно...


 
Александр из Минска ©   (2003-10-07 16:46) [12]

Я предлагаю ВЗЯТЬ КАКОЙ-НИБУДЬ ListBox или Memo, и потом сохранять их данные таким образом Memo1.Lines.SaveToFile("1.txt"); А загружать Memo1.Lines.LoadFromFile("1.txt"); Потом смотришь кол-во строк в Memo - Memo1.Lines.Count ( ВОТ ТЕБЕ И ДЛИНА МАССИВА). Я почти всегда так делаю, когда у меня массив должен создаваться динамически или неизвестна его длина.


 
Sergp ©   (2003-10-07 16:50) [13]


> Skier © (07.10.03 16:40) [11]
> Разберись почему и многое станет ясно...


Так ведь я для этого и прошу Вашей помощи...


 
Palladin ©   (2003-10-07 16:51) [14]

прочитай что есть SizeOf


 
Skier ©   (2003-10-07 16:52) [15]

>Sergp © (07.10.03 16:50) [13]
sizeof(nodelist)); это размер указателя, а не массива

Length(nodelist) - длина массива (11)
Length(nodelist) * sizeof(InfoNode) - размер массива


 
Sergp ©   (2003-10-07 16:59) [16]


> Александр из Минска © (07.10.03 16:46) [12]
> Я предлагаю ВЗЯТЬ КАКОЙ-НИБУДЬ ListBox или Memo, и потом
> сохранять их данные таким образом Memo1.Lines.SaveToFile("1.txt");
> А загружать Memo1.Lines.LoadFromFile("1.txt"); Потом смотришь
> кол-во строк в Memo - Memo1.Lines.Count (ВОТ ТЕБЕ И ДЛИНА
> МАССИВА). Я почти всегда так делаю, когда у меня массив
> должен создаваться динамически или неизвестна его длина.


так ведь я также могу переписать все это используя read, readln, write, writeln и работать с текстовым файлом.
Но ИМХО у меня проблемы именно с тем что массив динамический, а с такими массивами я раньше не пробовал работать. А писать нечто типа NodeList:array[0..10000] of InfoNode; где объявлять массив с кол. элементов, которое будет наверняка превышать требуемое значение, мне как-то не нравится...
К тому же хочется узнать что я все же здесь не так "намутил".


 
Reindeer Moss Eater ©   (2003-10-07 17:03) [17]

TFileStream,TWriter + TWriter.WriteListBegin + TWriter.WriteListEnd + методы записи различных типов данных у TWriter
+ итерация по массиву


 
Александр из Минска ©   (2003-10-07 17:04) [18]

Тогда создай Мемо или ListBox тоже динамически и вставляй, и удаляй сколько влезет. Такое решение подойдет?


 
Skier ©   (2003-10-07 17:09) [19]

assignfile(f,"nodelist.dat");
rewrite(f);
blockwrite(f,nodelist[0], Length(nodelist) * sizeof(InfoNode));
closefile(f);

//..............................

assignfile(f,"nodelist.dat");
SetLength(nodelist, FileSize(f) div sizeof(InfoNode));
blockread(f,nodelist[0],Filesize(f));
closefile(f);


 
Skier ©   (2003-10-07 17:10) [20]

sorry...

assignfile(f,"nodelist.dat");
reset(f);
SetLength(nodelist, FileSize(f) div sizeof(InfoNode));
blockread(f,nodelist[0],Filesize(f));
closefile(f);


 
Chlavik ©   (2003-10-07 17:27) [21]


> Я предлагаю ВЗЯТЬ КАКОЙ-НИБУДЬ ListBox или Memo, и потом
> сохранять их данные таким образом Memo1.Lines.SaveToFile("1.txt");
> А загружать Memo1.Lines.LoadFromFile("1.txt"); Потом смотришь
> кол-во строк в Memo - Memo1.Lines.Count (ВОТ ТЕБЕ И ДЛИНА
> МАССИВА). Я почти всегда так делаю, когда у меня массив
> должен создаваться динамически или неизвестна его длина


Может Tstrings было бы удобнее заюзать :)
А так не пробовал :)



procedure ReadFile;
var Data:array of Trecord;
f:file of TRecord;
s:string;
i,n:integer;
begin
s:="d:\Data.dat";
AssignFile(F,S);
ReWrite(f);
i:=FileSize(f); // длина масива;
n:=0;
SetLength(Data,i);
While not Eof(f) do
begin
Read(f,Data[n]);
inc(n);
end;
CLoseFile(f);
// ...
//...
SetLength(data,0);
end;

procedure SaveFile;
var Data:array of Trecord;
f:file of TRecord;
s:string;
i,n:integer;
begin
s:="d:\Data.dat";
AssignFile(F,S);
Reset(f);
for i:=Low(data) to high(data) do write(f,data[i]);
CLoseFile(f); //That"s all :)
end;




 
Sergp ©   (2003-10-07 17:31) [22]

Skier © (07.10.03 17:10) [20]

Спасибо.. Я понял. Хотя почему-то когда ставил твой код, то вылезала ошибка.
Переписал так:

type
InfoNode=record
parent:integer;
fileNum:cardinal;
text:string[116]; // Уменьшил до 116, чтобы sizeof(infonode)=128
end;

//Запись
assignfile(f,"nodelist.dat");
rewrite(f,128);
blockwrite(f,nodelist[0],length(NodeList));
closefile(f);

//Чтение
assignfile(f,"nodelist.dat");
reset(f,128);
SetLength(nodelist,FileSize(f));
blockread(f,nodelist[0],Filesize(f));
closefile(f);

Уже все работает...!!!!


 
Chlavik ©   (2003-10-07 17:33) [23]

Через мой алгоритм можеш хоть и string[255]


 
Skier ©   (2003-10-07 17:35) [24]

assignfile(f,"nodelist.dat");
rewrite(f, 1);
blockwrite(f,nodelist[0], Length(nodelist) * sizeof(InfoNode));
closefile(f);

//..............................

assignfile(f,"nodelist.dat");
reset(f, 1);
SetLength(nodelist, FileSize(f) div sizeof(InfoNode));
blockread(f,nodelist[0],Filesize(f));
closefile(f);


 
Sergp ©   (2003-10-07 17:35) [25]

type
InfoNode=record
parent:integer;
fileNum:cardinal;
text:string[116]; // Уменьшил до 116, чтобы sizeof(infonode)=128
end;

Хотя есть вопрос. Вроде бы integer и cardinal занимают по 4 байта, итого 4+4+116=124, а sizeof(infonode)=128 ?


 
icWasya ©   (2003-10-07 17:36) [26]

только
assignfile(f,"nodelist.dat");
rewrite(f, sizeof(InfoNode));// - !!!
blockwrite(f,nodelist[0],length(NodeList));
closefile(f);


 
Skier ©   (2003-10-07 17:36) [27]

>Sergp © (07.10.03 17:31) [22]
не надо "уменьшать" ! Надо добиться чтобы работало на "любых комбинациях"...


 
Sergp ©   (2003-10-07 17:38) [28]

rewrite(f, 1);
reset(f, 1);

М-да... Я забыл что по умолчанию будет 128...


 
Sergp ©   (2003-10-07 17:40) [29]

Skier © (07.10.03 17:36) [27]
>Sergp © (07.10.03 17:31) [22]
не надо "уменьшать" ! Надо добиться чтобы работало на "любых комбинациях"...

Ну это уже не проблема....
Я не пробовал но думаю что можно и так:
reset(f,sizeof(infonode));


 
Skier ©   (2003-10-07 17:43) [30]

>Sergp © (07.10.03 17:40) [29]

> Ну это уже не проблема....

Это гланая проблема.


> но думаю что можно и так:

Сомневаюсь !


 
Chlavik ©   (2003-10-07 17:49) [31]

Кстати если сохранить
blockwrite(f, Pointer(Integer(nodelist[0])-4),length(NodeList)+4); то в файл запишется и длина массива.!



Страницы: 1 вся ветка

Текущий архив: 2003.10.20;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.018 c
1-65551
TGrigory
2003-10-07 21:13
2003.10.20
TListView - как добавлять новые пункты?


7-65655
JohnJ
2003-08-03 01:33
2003.10.20
телефон подключён к модему...


1-65539
sasach
2003-10-08 09:06
2003.10.20
посоветуйте...


3-65387
123
2003-09-27 17:03
2003.10.20
release mdb


1-65512
Viktor Kushnir
2003-10-07 19:27
2003.10.20
Hot Keys