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

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

  1. Структура файла
  2. Запись в файл
  3. Чтение из файла
  4. Программка для практики


В программе из прошлого выпуска было кое-что незнакомое. Сейчас попробуем во всем разобраться.

Для начала надо сказать несколько слов о структуре самого файла. Каждый файл состоит из структурных элементов, определяющиеся типом файла. Каждому элементу файла можно присвоить какой-то порядковый номер, который, если файл не изменялся, будет иметь постоянное значение. Так файл можно сравнить с массивом данных с той разницей, что файл не имеет постоянный длины и заканчивается специальным символом маркером конца файла (EOF - End Of File). Он сигнализирует о том, что достигнут конец файла.

У каждого файла есть так называемый указатель. Он нужен для того, чтобы указывать на тот элемент, который будет обрабатываться (читаться или записываться). На каждый файл есть только один указатель, поэтому в каждый момент времени доступен только один элемент. После чтения или записи элемента указатель увеличивается на единицу, поэтому при циклической или цепочечной записи в файл вам можно не бояться за то, что какие-то данные окажутся "затертыми". Кроме этого в типизированных и нетипизированных файлах есть возможность самому устанавливать указатель на нужный элемент (но об этом в другой раз). В самом начале, когда файл только открыли, указатель устанавливается на самый первый элемент.

Один из циклов в программе предыдущего выпуска был организован следующим образом:

While not EOF(F2) do
     begin
         Read(F2, ch);
         Write(ch);
     end;

Алгоритм его работы: пока не достигнут конец файла выполнять тело цикла. Здесь EOF - логическая функция, которая возвращает истинное значение, если указатель находится за маркером конца файла, иначе она вернет ложное значение. В теле данного цикла производится чтение из файла, связанного с переменной F2, т.е. указатель модифицируется (увеличивается на единицу). Цикл работает до тех пор, пока указатель не окажется за маркером конца файла. В результате этого мы прочитаем весь файл.

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

Запись

Для этой операции файл должен быть открыт для записи. Запись осуществляется с помощью процедур Write и WriteLn. Первая применима как типизированным так и текстовым файлам. Вот их описание:

          procedure Write(F, V1 [, V2,...,Vn ] );

Где F - переменная файлового типа, кроме нетипизированного. Vi (i=1…n) - записываемые данные. Их типы должны соответствовать типу переменной F. В случае, если параметр F опущен запись будет производиться на стандартное устройство вывода (обычно дисплей).

Процедура WriteLn отличается от предыдущей тем, что применяется только для текстовых файлов, она выполняет те же действия, что и Write, но при этом записывает в файл маркер конца строки. Т.е., грубо говоря, после записи данных в файл переходит к следующей строке файла. Ее описание:

  procedure Writeln([ var F: Text; ] V1 [, V2, ...,Vn ] );

Где F и Vi (i=1…n) имеют тот же смысл, что и для процедуры Write.

Я думаю, вам не составит труда разобраться в следующей программе:

Uses
    CRT;
const
    FName1    =   'Test1.pas';
    FName2    =   'Test2.pas';
    n         =   5;
var
    F    :  Text;
    st   :  string;
    i    :  byte;
begin
    ClrScr;
    Assign(F, FName1);
    Rewrite(F);
    For i:=1 to n do
        Write(F, 'String  ', i);
    Close(F);
    Assign(F, FName2);
    Rewrite(F);
    For i:=1 to n do
        WriteLn(F, 'String  ', i);
    Close(F);
end.

Созданные Файлы Test1.pas и Test2.pas вы можете просмотреть в любом текстовом редакторе, тогда и увидите отличия двух циклов в этой программе.

Чтение

Чтение осуществляется с помощью процедур Read и ReadLn. Процедуру Read можно применить как к типизированным так и к текстовым файлам. Она считывает один или несколько компонентов из файла и присваивает их переменным, переданных ей в качестве параметра. Ее описание:

          procedure Read(F , V1 [, V2,...,Vn ] );

здесь F и Vi (i=1…n) имеют тот же смысл, что и в процедуре Write.

Процедура ReadLn применяется только к текстовым файлам. Она выполняет те же действия, что и Read, с той лишь разницей, что после считывания переходит к следующей строке файла. Ее описание:

   procedure Readln([ var F: Text; ] V1 [, V2, ...,Vn ]);

В случае, если параметр F не будет указан, то ввод данных будет производиться со стандартного устройства ввода (обычно клавиатура).

Наберите в окне редактора Pascal'я следующий текст, сохраните его (обязательно!) под именем Test3.pas и запустите. В результатах вы разберетесь сами.

< pre class="prog"> Uses CRT; const F1 = 'Test3.pas'; var F : Text; st : string; begin ClrScr; Assign(F, FName1); Reset(F); While not Eof(F) do begin ReadLn(F, st); WriteLn(F); end; Close(F); ReadKey; end.

Кстати, если в цикле вместо ReadLn(F, st); написать Read(F, st);, то программа зациклится. А почему?

Теперь вам полностью должна быть понятна программа из прошлого выпуска.

Чтобы не было скучно приведу еще одну программку, в которой предлагаю разобраться вам самим:

Uses
    CRT;

Type

   TString10    = string[10];

   TString15    = string[15];

   TFriend      = record
       Name    : TString10;
       SirName : TString15;
       Age     : byte;
   end;

const
    YesChars  = ['Y', 'y', '­', 'Ќ'];
    NoChars   = ['N', 'n', ''', 'в'];
    FName1    = 'Record.pas';
    FName2    = 'String.pas';
    ch           : char = #0;

procedure   Wait;
    begin
      If WhereX >=70 then
         begin
            GotoXY(1, 79);
            WriteLn('Press any key...');
            ReadKey;
            ClrScr;
         end;
    end;

procedure   WaitKey;
    begin
      WriteLn('Are you wanting to continue?(Y/N) ');
      Repeat
        ch:=ReadKey;
        If ord(ch) = 0 then
           ch:=ReadKey;
      until  (ch in NoChars) or (ch in YesChars);
      ClrScr;
    end;

var
    st       :  string;
    FText    :  Text;
    FTFriend :  file of TFriend;
    Friend   :  TFriend;
begin
    ClrScr;
    WriteLn('Input data about your friend.');
    Assign(FTFriend, FName1);
    Assign(FText, '');
    Rewrite(FTFriend);
    Reset(FText);
    Repeat
      Write('Name    : ');
      ReadLn(FText, FRiend.Name);
      Write('SirName : ');
      ReadLn(FText, FRiend.SirName);
      Write('Age     : ');
      ReadLn(FText, FRiend.Age);
      Write(FTFriend, Friend);
      WaitKey;
    until  ch in NoChars;
    Close(FTFriend);
    Reset(FTFriend);
    Assign(FText, FName2);
    ReWrite(FText);
    While not Eof(FTFriend) do
       begin
           Read(FTFriend, Friend);
           WriteLn(FText, Friend.Name);
           WriteLn(FText, Friend.SirName);
           WriteLn(FText, Friend.Age);
       end;
    Close(FText);

    ClrScr;
    Reset(FTFriend);
    WriteLn('Read from file of TFriend:');
    While not Eof(FTFriend) do
      begin
          Read(FTFriend, Friend);
          WriteLn('Name    : ', Friend.Name);
          WriteLn('SirName : ', Friend.SirName);
          WriteLn('Age     : ', Friend.Age);
          WriteLn('=====================');
          Wait;
      end;
    Close(FTFriend);
    ReadKey;
    ClrScr;
    Reset(FText);
    WriteLn('Read from Text file.');
    While not Eof(FText) do
      begin
         ReadLn(FText, st);
         WriteLn('Name    : ', st);
         ReadLn(FText, st);
         WriteLn('SirName : ', st);
         ReadLn(FText, st);
         WriteLn('Age     : ', st);
         WriteLn('======================');
         Wait;
      end;
    ReadKey;
    Close(FText);
end. 

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

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

 

Hosted by uCoz