Rambler's Top100


Сегодня мы поговорим о бестиповых файлах. Бестиповые файлы позволяют записывать произвольные данные в файл. Для создания файловой переменной, мы должны указать просто слово 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 я+¦ ч+Ь ўч+ я_+ я_+ я+¦ _ўў ч+Ф _¦Ф я+¦ ч¦н __ў ўў_ ў_ў ў_+ ўч+ ___ ч+н ч¦Ф _ў_ я+н ч+Ь ч+М ў__ я+н ч¦М ч¦Д я+е
а ведь и не скажешь, что картинка :)

Программа

Сегодня мы не будем особо выдумывать и напишем очередную програмку, которая копирует один файл в другой. Естесственно мы будем считать, что оба файла не типизированные. И как всегда :) скопируем autoexec.bat в autoexec.txt:

program CopyFile;

var
  FromF, ToF: file;
  NumRead, NumWritten: Word;
  Buf: array [1..100] of Char;

begin
  Assign(FromF, 'C:\autoexec.bat');
  Reset(FromF, 1);
  Assign(ToF, 'C:\autoexec.txt');
  Rewrite(ToF, 1);

  repeat
    BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
    BlockWrite(ToF, Buf, NumRead, NumWritten)
  until (NumRead = 0) or (NumWritten <> NumRead);

  Close(FromF);
  Close(ToF)
end.

Здесь я уже использую параметры, которые возращают число успешно прочитанных символов. После вызова

BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
в NumRead у нас окажется число прочитанных байт, потом мы вызываем BlockWrite:
BlockWrite(ToF, Buf, NumRead, NumWritten)
Поэтому даже если мы прочитали меньше, чем sizeof (Buf) (ну ка скажите моментом, чему равено sizeof (buf)? если вы потратили на это больше двух секунд, значит вам нужно больше заниматься :). Так вот даже если мы прочитали меньше, чем sizeof (Buf), то запишем мы ровно столько, сколько прочитали.




программирование на Паскале, Pascal, BP, TP, BorlandPascal, TurboPascal turbo pascal 7.0, borland pascal 7.0, языки программирования, pascal учебник
Рад приветствовать! =) Начнем мы с истории данного сайта. Изначально он разрабатывался как типично авторский проект, не неся в себе особых целей. Я лишь хотел освоить азы html верстки и опробывать свои силы в разработке web-сайтов. Тематика "программирование на Паскале" была выбрана не случайно, до этого я долго изучал этот ЯП и всё это вылилось в написание собственного самоучителя по Паскалю. Сейчас это всё вспоминается с некоторой долей иронии и улыбкой на лице. В нынешнее время я полностью занимаюсь web-разработками и отошел от прикладного программирования, но данный проект решил всё же не забрасывать и вдохнуть в него новую жизнь, освежив дизайн и контент.

С уважением, Евгений Злобин
турбо-паскаль скачать, файлы паскаль, бесплтано скачать pascal