Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.006 c
14-65596
blackweber
2003-10-01 12:24
2003.10.20
win 2000 server registry


1-65546
Tetros
2003-10-06 19:06
2003.10.20
Исполняемый код!


3-65385
Виктор
2003-09-27 21:30
2003.10.20
Проверка типов полей


3-65314
Kremen
2003-09-30 11:50
2003.10.20
Инструменты редактирования


3-65348
Alexander Vasjuk
2003-09-29 13:15
2003.10.20
Создание таблицы DBase с помощью ADO





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский