![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сохранение массива Record ов в файл [D5, WinXP]
Blacker77 © (2002-10-08 05:03:00)Hi Уважаемый Pipl!
Подскажите PLS как сделать Subj?
Есть тип:
TInfo = record
Disk :DWord;
Name : string;
FileSystemName : String;
Serial : String;
Size :Longint;
Text :String;
end;
Нужно из него образовать массив:
Info :array of TInfo;
А вот теперь надо его (массив) сохранить в файл.
Как это делается??????????? Я уже себе бошку сломал!
HEEEEEEEEEEEEEELP PLEEEEEEEEEEEEZZZZZZZZZ!
Заранее благодарен!
Rouse_ (2002-10-10 00:35:00) [1]У блин, тоже поторопился, об этом уже написали ;)))
Rouse_ (2002-10-10 00:28:00) [2]вместо String используй к примеру String[255], ну короче заранее установи размер переменной и никаких проблем с f: file of TInfo; не будет
Желаю успехов
Tano (2002-10-09 22:00:00) [3]remark:
//если String...... длина = Length(String)
и
BlockRead(F, String1, Length(String1))
ЗЫ торопился :)
Tano (2002-10-09 21:57:00) [4]Простого решения нет. Такую Record напрямую не сохранишь.
Для таких целей я пишу цикл с НЕтипизированным файлом, только открывать его надо Reset(F,1), чтобы побайтово отсчитывался.
Готового кода предложить не могу, но алгоритм записи:
ДЛЯ записи[i] DO
begin
BlockWrite(F, переменная_1, длина);//...простые переменные
BlockWrite(F, переменная_N);
//если String - тоже верно записывает, если длина = SizeOf(String), но необходимо завести дополнительные переменные, в которых запишешь длину строки и поместить их перед самой строкой.
BlockWrite(F, переменная_длина_строки_String1
BlockWrite(F, String1, Length(String1));
end;
При чтении последовательность та же, только
BlockWrite меняешь на BlockRead и для каждой String читая длину очередной строки вызываешь SetLength(MyString1, прочитанная_длина), затем уже BlockRead(F, MyString, Length(String1))
Извеняюсь за расплывчатое объяснение, да и принцип можно придумать поумнее, наверное. Плюс его в том, что работает быстро при больших объемах информации и в том что он работает именно для произвольных конструкций Record.
P.S. я здесь на форуме натыкался на объяснение расположения в памяти переменной типа String. Если разобраться с деталями этого, то многое можно упростить.
AndreyAG (2002-10-09 10:11:00) [5]объекты класса TStrings имеют метод LoadFromFile и SaveToFile
заносиш каждое поле своего recorда в строку из TStrings и используеш SaveToFile как восстановить думаю понятно
MaratFromTomsk (2002-10-09 09:59:00) [6]поглядел как у борланда сделано
спользовать надо нетипизированный файл
запись должна быть фиксированного размера
то есть поля не м.б. string а shortstring
что то типа
TInfo = record
Disk: DWord;
Name: string[8];
FileSystemName: string[30];
Serial: string[20];
Size: Longint;
Text: string[255];
end;
// создать файл
procedure CreateFile(const filename: string);
begin
AssignFile(f, filename);
Rewrite(f);
end;
// считать запись
procedure ReadRecord(recno: integer; out r: TInfo);
begin
Seek(f, recno*SizeOf(TInfo));
Read(f, r);
end;
и т.д
но если размер записи не фиксирован,
то все уже зависит от задачи
мне например нравиться юзать классы TReader, TWriter
unit Classes,
или наирулезнейший XML в редакции MSXML,
можно какую нить СУБД
Nomad.kz (2002-10-09 09:42:00) [7]еще я где-то читал (у Пачеки, имхо), что для таких целей надо организовывать packed record, в целях устранения выравнивания.
Anatoly Podgoretsky (2002-10-09 09:34:00) [8]Это естественно работает, но смысла писать указатели нет, для начала надо перейти на короткие строки, только вот откуда ты взял такие странные функции для File of
MaratFromTomsk (2002-10-09 09:24:00) [9]Еще в стандартном паскале от Вирта
можно было определить файл
fr: File of TMyRecordType;
и читать и писать с помощью Get Put
неужели это не работает?!!!
Bsl (2002-10-09 09:03:00) [10]А ты, наверное читаешь в "пустую" память.
Перед чтением нужно определить размер массива: SetLength(Массив, Кол-во элементов);
А вообще, string нельзя просто так сохранять - т.к. "string" - это указатель на область памяти. Можно использовать string[255] - это старые строки паскаля.
А если тебе надо хранить информацию типа MEMO - то это уже другая фишка - или ты думаешь, что в БД поля типа МЕМО просто так придумали, а размер текстовых полей ограничили 255 байтами!
Aleks1 (2002-10-09 03:28:00) [11]2 Blacker77
Тогда скажи как читаешь и как ругается.
Blacker77 (2002-10-08 20:48:00) [12]Дык всеравно не получается.... записывает нормально, но при чтении ругается!
MBo (2002-10-08 06:15:00) [13]Используй, например, TFileStream
Пишешь: Количество записей
Запись: При желании общую длину записи (с учетом длин строк)
Cтатические поля (dword) писать тривиально
Длина строки
Ее содержимое
fstream.write(info[i].name[1],Length(info[i].name))
При чтении сначала SetLength для каждой строки