| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Запись массива в файл |
| Автор: Alex 24.11.2002, 23:46 |
| Привет всем. У меня вопрос относительно записи массива в файл. Допустим, у меня массив: myarray: array [0..99] of integer Как правильно его записать в файл? Я делаю так: mystream:=TFileStream.Create(myfile, fmCreate); //создаю файл mystream.WriteBuffer(myarray,100); //запись массива в файл mystream.free; //освобождение потока Вроде бы все работает. Но я потом не могу его прочитать. Читаю так: mystream:=tfilestream.Create(myfile,fmOpenRead); mystream.ReadBuffer(myarray,100); mystream.free; Выдает сообщение, что программа выполнила недопустимое действие и будет закрыта. В чем проблема. |
| Автор: Vit 25.11.2002, 00:27 |
| Если только это то можно использовать: Type Tmyarray= array [0..99] of integer; Var myarray:Tmyarray; F:file of Tmyarray; ... запись: assignFile(f, 'myfile'); rewrite(f); write(f,myarray) closefile(f) чтение: assignFile(f, 'myfile'); reset(f); read(f,myarray) closefile(f) |
| Автор: Alex 25.11.2002, 03:42 |
| Вообще-то я там записал сокращенный вариант записи файла. На самом деле в начало я записываю заголовок типа header: record of name: string[32]; version: integer; sizex: integer; sizey: integer; end; Все это делаю через поток (как в первом примере), а потом после заголовка уже записываю сам массив, так что я думаю что твой пример не пойдет. |
| Автор: Vit 25.11.2002, 03:52 |
| Тогда приводи свой код и полную структуру файла, так как ошибка скорее всего не в том куске который ты привёл, а в том что ты должен читать инфу после header и видимо позиционируешь чтение не с того места, или ещё что-то... Дай более полную инфу и я подумаю, как это сделать |
| Автор: Alex 29.11.2002, 00:40 |
| Делаю так: Код для записи в файл //------------------- procedure TForm1.ConvertBtnClick(Sender: TObject); var Header: record //заголовок файла-карты Name: string[16]; //имя файла version: integer; //номер версии SizeX: integer; //размер карты по Ох SizeY: integer; //размер карты по Оу HeightKoef: single; //коэффициент end; koef: single; headersize: integer; //размер заголовка x1,y1,x,y: integer; heightmap: array of array of byte; //динамический двумерный массив arraysize: integer; //размер массива outstream: tstream; //поток для записи конечного файла outputfile: string; //выходящий файл begin ... setlength(heightmap,x,y); //устанавливаю размер массива arraysize:=x*y; //размер массива в байтах (приходится вычислять так, т.к. sizeof(heightmap) не работает (всегда возвращает 4)???) for x1:=0 to x-1 do for y1:=0 to y-1 do begin ... heightmap[x1,y1]:=... //здесь заполняю массив end; Header.Name:='HeightMap'; //запись заголовка header.version:=1; //запись заголовка header.SizeX:=x; //запись заголовка header.Sizey:=y; //запись заголовка header.heightkoef:=koef; //запись заголовка headersize:=sizeof(header); //возвращает размер заголовка OutStream:=TFileStream.Create(OutputFile, fmCreate);//создает поток для записи конечного файла outstream.WriteBuffer(header,headersize); //запись заголовка в файл outstream.WriteBuffer(heightmap,arraysize);//запись массива в файл OutStream.Free; //освобождение потока end; //------------------- Код для чтения из файла //------------------- procedure TForm1.LoadSourceMenuClick(Sender: TObject); var mapfile: tstream; //поток для чтения файла myfile: string; //имя файла Header: record //заголовок файла-карты Name: string[16]; //имя файла version: integer; //номер версии SizeX: integer; //размер карты по Ох SizeY: integer; //размер карты по Оу HeightKoef: single; //коэффициент для расчета высот end; headersize: integer; //размер заголовка heightmap: array of array of byte; //двумерный динамический массив arraysize: integer; //размер массива карты высот x,y: integer; begin ... mapfile:=tfilestream.Create(myfile,fmOpenRead);//создаем поток для чтения файла headersize:=sizeof(header); mapfile.ReadBuffer(header,headersize); //читаем заголовок x:=header.SizeX; y:=header.SizeY; setlength(heightmap,x,y); //устанавливаем размер массива arraysize:=x*y; //вычисляем размер массива в байтах mapfile.ReadBuffer(heightmap,arraysize); //считываем массив mapfile.free; end; //------------------- Обе эти процедуры работают. Файл записывается нормально (количество записанных байт соответствует требуемому значению (sizeof(header)+x*y - в моем случае)). Считывается заголовок тоже нормально. Проблема в самом массиве, когда я пытаюсь достать из него какое-либо значение, например heightmap[0,0] - ЗДЕСЬ ОШИБКА. |
| Автор: Alex 6.12.2002, 02:58 |
| Привет, Vit. Мой вопрос еще не закрыт. Жду ответа... |
| Автор: Vit 6.12.2002, 04:56 | ||||
| Сорри, забыл... Так посмотрел твой код 1) Мусор он у тебя в файл пишет, а не массив, так как реально он туда пихает указатель а не содержимое. Кстати поэтому у тебя и размер не работал - естественно - он размер указателя тебе возвращает. Исправь на:
Чтение сделай точно так же:
2) У меня всё равно неправильно читает, и заглянув внутрь файла я увидел посреди данных мусор, такое впечатление что двумерный массив не хранится в памяти единым блоком (или хрен его знает почему так). Если заменить на одномерный массив то всё нормально. Вывод - хочешь ковыряйся дальше, нет - пиши одномерным массивом - одним большого размера, или просто пиши/читай в цикле одномерные массивы. Для отладки таких вещей удобно сделать например следующее - берёшь массив 20х20 заполняешь например $40 - пишешь в файл, затем открываешь файл в просмотрщике и смотришь что у тебя записано |