Теория
Сегодня мы поговорим о бестиповых файлах. Бестиповые файлы позволяют записывать произвольные данные в файл.
Для создания файловой переменной, мы должны указать просто слово file:
var
F : file;
Принцип работы с бестиповыми файлами такой же, как и с типовыми: сначала связываем файловую переменную с файлом с помощью процедуры Assign. Затем открываем его с помощью процедур Reset или Rewrite. А после окончания работы он должен быть закрыт процедурой Close.
Однако не всё так просто, как хотелось бы :( Помните в прошлый раз я написал дополнительные параметры к функциям Rewrite и Rest ? Для типовых файлов эти параметры были не важны, а вот для бестиповых.... так, что читайте ниже дополнительное описание этих процедур:
- procedure Reset(var F : File; Recsize: Word );
- procedure Rewrite(var F: File ; Recsize: Word );
в обоих случаях параметр Recsize задаёт число байтов, считываемых из файла или записываемых в него за одно обращение. Минимальное значение Recsize 1 байт, максимальное - 64 К байт. По умолчанию он равен 128 байтам.
А вот запись и чтение осуществляется другими процедурами.
procedure BlockRead(var F: File; var Buf; Count: Word; var Result: Word);
Эта процедура служит для чтения из файла. F - файловая-переменная. Buf - переменная любого типа, Count - число блоков, которое нужно считать в Buf. Необязательный параметр Result - число успешно прочитанных блоков. В случае успеха Result = Count. Например считаем из файла строку:
program test;
var
FromF: file;
Buf : string;
begin
Assign(FromF, 'C:\1.txt');
Reset(FromF, 1);
BlockRead (FromF, Buf, SizeOf(Buf));
Close(FromF)
end.
Мы не используем параметр Result при вызове BlockRead. Размер нашего буффера можно сосчитать с помощью уже известной функции sizeof. Кстати, если вы напишите после этого строку write (buf), то увидите совсем не строку из файла, а нечто на неё похожее. BlockRead до лампочки читаете вы из файла строку или вещёственное число, она просто читает заданное ей количество байт и записывает их по аддресу переменной buf. Т.е. мы дали команду считать 256 байт (SizeOf(Buf) = 256) и записать результат в Buf. BlockRead не будет разбираться, что Buf у нас это строка, и не запихнёт в Buf[0] размер строки. В buf[0] будет первый байт, находящийся в файле! А это может быть, например нулевой символ и тогда buf[0] = #0 и на экран ничего не выведется.
Ну и соответственная процедура для записи в файл:
procedure BlockWrite(var f: File; var Buf; Count: Word; var Result: Word);
Соответственно эта процедура пишет в файл F, Count байт из Buf. Result так же является не обязательным параметром, и в нём возвращается число блоков успешно записанных процедурой.
Например запишем в файл строку, которую ввёл пользователь:
var
FromF: file;
Buf : string;
begin
ClrScr;
Assign(FromF, 'C:\2.txt');
rewrite(FromF, 1);
readLn (buf);
BlockWrite(FromF, Buf, SizeOf(Buf));
Close(FromF)
end.
BlockWrite так же по барабану строка это у нас или нет. Поэтому в результате создасться файл, размером в 256 байт. Даже если вы ввели строку из 3-х символов, размер не изменится. При этом первый байт в файле - это символ с номером, равным длинне строки.
Однако рамер одного символа = 1 байту, размер строки = buf [0], поэтому преобразовав вызов процедуры в такой, мы получим нужный результат (т.е. такой результат, что бы размер файла соответствовал размеру строки + 1):
BlockWrite(FromF, Buf, ord (Buf[0]) + 1);
Кстати практически все файлы являются не типизированными. Откройте, например, любой bmp через текстовый редактор. Вот так выглядят несколько строк любимых Облачка.bmp:
BM:_ : ( А р _ + - A A +н{ _¦Д +нs _н{ _+Ф _¦{ _¦М _+М _¦Ь я_+ яч_ ч¦е ч++ ч+н ч+е ўяч ячч _+Ь +¦{ _нs я_¦ ч+¦ ўўў ўяя _+Д ўўя ч+¦ яч+ ч+¦ ч¦Ь яч+ я++ яя_ ўч_ ўя_ ўўч _¦s я+¦ ч+Ь ўч+ я_+ я_+ я+¦ _ўў ч+Ф _¦Ф я+¦ ч¦н __ў ўў_ ў_ў ў_+ ўч+ ___ ч+н ч¦Ф _ў_ я+н ч+Ь ч+М ў__ я+н ч¦М ч¦Д я+е
а ведь и не скажешь, что картинка :)