Немного о файлах. Часть 4

В этом выпуске:

  1. Новые процедуры
  2. Маленькая хитрость
  3. Программка для практики


И снова здравствуйте, уважаемые любители программирования на языке высокого уровня Pascal.

Если у вас больше нет вопросов по пройденным материалам, то мы смело можем продолжать двигаться вперед.
Раз уж в прошлый раз мы заговорили об ориентировании в файле, то полезно было бы узнать насколько широко мы можем размахнуться, т.е. какова длина файла. А как раз для этого есть замечательная функция FileSize. Читаем паскалевский хелп по этой функции:

Возвращает текущий размер файла. Ее обявление:

function FileSize(var F): Longint;

где F - файловая переменная. Эта функция возвращает количество компонентов в файле F. Для пустого файла она вернет нулевое значение. Выполнение этой функции можно контролировать с помощью директивы {$I-}. Так же следует помнить, что ее нельзя применять к текстовому файлу, и файл обязательно должен быть открыт.

Выше было сказано, что функция возвращает количество структурных элементов. Не нужно путать это значение с длиной файла, измеряемой в байтах. На этом ошибались многие мои знакомые.

Наберите следующую программу и запустите ее:

Uses
    CRT, Dos;
const
     FName = 'Longint.lnt';
Var
   FLong  : file of LongInt;
   FByte  : file of byte;
   L      : longint;
   B      : byte;
begin
  ClrScr;
  Assign(FLong, Fname);
  ReWrite(FLong);
  For L :=  1 to 30 do
      Write(FLong, L);
  WriteLn('As file of longint = ', FileSize(FLong));
  Close(FLong);
  Assign(FByte, FName);
  Reset(FByte);
  WriteLn('As file of byte = ',FileSize(FByte));
  Close(FByte);
  ReadKey;
end .

Вы увидите, что применив функцию FileSize к одному и тому же файлу, она вернет разные значения. Ведь в первом случае компонентами файла являются числа типа LongInt, а во втором - числа типа byte. Кстати, почему значения во втором случае всегда ровно в четыре раза меньше, чем в первом?

Мы уже рассмотрели некоторые процедуры по работе с содержимым файла (чтение, запись, добавление новых элементов), а что, если понадобится удалить информацию из файла. Как раз для этих целей служит замечательная процедура Truncate. Она усекает файл от текущей позиции указателя файла до конца. Ее объявление:

procedure Truncate(var F);

где F - файловая переменная любого типа за исключением текстового. Естественно файл прежде должен быть открыт. После выполнения этой операции указатель файла устанавливается на end-of-file (на конец файла). То есть, если применить функцию Eof(F), то она вернет значение True. Для понимания вышесказанного предлагаю поэкспериментировать со следующей программой:

Uses
    CRT;
const
     FName = 'Test1.Pas';
var
   F  : file of char;
   ch : char;
begin
    ClrScr;
    Assign(F, FName);
    Rewrite(F);
    For ch:='A' to 'Z' do begin
       Write(F, ch);
    end;
    WriteLn('Удаляем с 20 символа');
    Seek(F, 19); {Счет ведется с нуля!!!}
    Truncate(F);
    WriteLn('Файл после удаления: ');
    Reset(F);
    While not Eof(f) do begin
        Read(F, ch);
        Write(ch, ' ');
    end;
    Close(F);
    ReadKey;
end. 

Раз уж мы можем удалять часть файла, то почему бы ни удалить файл целиком. В предыдущих выпусках, да и в этом тоже, программки для практики создавали файлы, которые, возможно, мешали вам. Обещаю, что этого больше не повторится, и процедура Erase поможет нам в этом. Ее описание: Erase удаляет внешний файл. Объявление:

procedure Erase(var F);

где F - файловая переменная любого типа. Как видите все довольно просто. Нужно только помнить, что ее нельзя применять к открытому файлу. И так как эта процедура относится к операции ввода\вывода, то для контроля ее выполнения можно использовать функцию IOResult, и, если все прошло успешно, то она вернет нулевое значение.

Кстати, по поводу файлового ввода\вывода есть одна маленькая хитрость. Вы можете связать (с помощью процедуры Assign) файловую переменную Input c каким-нибудь файлом, открыть его для чтения, и тогда всякий раз, когда вы будете писать Read или ReadLn, значения переменных, которые вы будете передавать в качестве параметра этим процедурам, будут считываться из того файла, с которым вы связали переменную Input. Аналогично, связав переменную OutPut с каким - нибудь файлом процедуры Write и WriteLn запишут информацию в этот файл. Этот способ можно применять тогда, когда вам лень писать файловую переменную в качестве первого параметра процедур ввода\вывода. Однако применять этот метод нужно аккуратно, следя за соответствием типов.

Как говорится, теория без практики слепа. И как обычно в завершении предлагаю вам программу для практики:

         

P.S: Некоторые из вас просят усложнения материала и задач для самостоятельного решения. Что же, я благодарен тем, кто высказывает свое мнение по поводу рассылки, и в свою очередь постараюсь учесть ваши пожелания.

Всего доброго!

[ в начало ] [спрашивайте]

© Чарышкин Олег

Рассылку поддерживает сайт www.turbopascal.tk