Форум: "Основная";
Текущий архив: 2003.10.20;
Скачать: [xml.tar.bz2];
ВнизКак сохранить в файл и загрузить из файла безразмерный массив Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.024 c