Файлы В общем случае файлом называется последовательность некоторых однотипных информационных компонентов, сохраняемая во внешней памяти компьютера под одним именем. На этом основании файл считается структурой данных. Полномасштабная работа с файлами принадлежит к прерогативам операционной системы. Здесь мы используем специальные команды создания, просмотра, копирования и удаления файлов, знакомимся с их свойствами, сортируем их, а также объединяем в иерархическую древовидную структуру каталогов. Однако выполнение всех перечисленных операций с файлами организуется и осуществляется, как правило, вручную. Средства работы с файлами, предусмотренные в Паскале, позволяют автоматизировать эти функции. Существуют задачи, для которых заранее невозможно определить количество выходных или входных данных. Оно определяется только в процессе решения конкретной задачи, то есть при работе программы. Поэтому возникла необходимость в специальной структуре данных, которая представляла бы собой последовательность компонентов, в общем случае разнотипных, причем длина этой последовательности заранее не определялась, а конкретизировалась при выполнении программы. К тому же, эта структура данных должна была бы храниться не в оперативной памяти компьютера, а на внешних устройствах. В современных алгоритмических языках такую структуру данных называют файлом. В отличие от рассмотренных выше структур данных – массивов, множеств и строк, при описании которых необходимо задавать их точный размер для выделения в оперативной памяти необходимого количества ячеек для их размещения, при описании файлов их размер не указывается. Вторым отличием от массивов – структур данных с произвольным (прямым) доступом к любому их элементу (можно обратиться, например, к пятому элементу вектора, предварительно не считывая предыдущие четыре элемента), файлы являются структурами, как с произвольным, так и с последовательным доступом – для обращения к их пятому элементу необходимо прочитать предыдущие четыре. Таким образом, файл – это упорядоченная совокупность однотипных элементов (типизированные файлы), имеющая произвольную длину, прямой или последовательный доступ. Аналогом файлов является магнитофонная лента: количество записей в ней заранее неизвестно, всегда доступна для прослушивания только текущая запись, и для прослушивания очередной записи необходимо прослушать или перемотать все предыдущие. Файлы, используемые в Паскале, делятся на физические (внешние) и логические (внутренние). Физические файлы являются средствами обмена данными и хранятся на внешних носителях. Это единственная структура, посредством которой данные, обрабатываемые программой, могут быть получены извне, а результаты работы программы могут быть переданы во внешний мир и сохранены. Таким образом, (физические) внешние файлы сохраняются после окончания работы программы, их создавшей, и данные, записанные в них, могут быть использованы для дальнейшей работы. Логические файлы хранятся в оперативной памяти компьютера во время работы программы, их создавшей, и стираются после окончания ее работы. На логическом уровне в качестве информационных компонентов файлов могут выступать любые структуры данных: числа, символы, строки, массивы, записи. Компонентами файлов не могут быть только другие файлы. На физическом уровне универсальным информационным компонентом любого файла является байт. Иначе говоря, содержимое любого файла представляет собой последовательность байтов. Взаимоотношения данной программы с последовательностью байтов данного файла могут строиться по-разному, в зависимости от того, каким определен тип файла в программе. В Паскале различают три типа внешних файлов: 1. типизированные 2. текстовые 3. нетипизированные Типизированные файлы Они предназначены для хранения данных только одного типа Паскаля: файл целых чисел, вещественных чисел, символов, массивов одного размера, строк одной длины, записей. Не существует только файла файлов и файла объектов. Перед началом работы с файлом его необходимо описать (объявить), указав его имя и тип компонентов (элементов). Объявить файл можно двумя способами: 1. указанием его имени и типа в разделе описания переменных Var : Var f_int : File Of Integer; описан файл целых чисел f_int, f_int – имя логического файла – файловой переменной Внимание! При описании файла его размер не указывается. Структура файла целых чисел: целое со знаком целое со знаком целое со знаком ... EOF EOF – End Of File – метка конца файла: символ с кодом 26 (CTRL+Z). Var f_char : File Of Char; описан файл символов f_char, f_char – имя логического файла – файловой переменной Структура файла символов: код символа код символа код символа ... EOF 2. указанием его типа в разделе определения типов TYPE и имени – в разделе описания переменных Var : Type TFile_int : File Var Of Integer; f_int : TFile_Int; Таким образом, можно перечислить отличия файла от, например, массива: файлы располагаются во внешней памяти – сохраняются после окончания работы программы, при описании файлов размеры их не задаются, они могут изменяться при работе программы, текущее количество элементов файла в каждый момент работы программы неизвестно, но всегда известно, где конец файла (метка EOF), в любой момент программно можно определить длину файла, добавлять в него новые элементы, считывать их, урезать его, переименовывать и даже уничтожить. Перед началом работы с файлом необходимо связать имя логического файла (файловую переменную) с физическим файлом на внешнем носителе: Assign(имя файловой переменной, ‘путь к физическому файлу’); Assign(f_int,’D:\User\f_int.dat’); f_int – имя файловой переменной (логического файла), D:\User\f_int.dat - полный путь к физическому файлу на внешнем носителе: диск D: директория (папка) User файл f_int_dat. Внимание! Желательно совпадение имени физического файла и имени файловой переменной; расширение имени типизированного файла .dat. После установления пути к физическому файлу его можно открыть: а) открытие нового файла для записи в него данных: ReWrite(f_int); При этом на внешнем носителе создается новый физический файл с заданным именем. Если файл с таким же именем уже существовал, то он очищается. С каждым файлом связан указатель текущего элемента (записи). В этом случае этот указатель становится в начало файла – элемент с номером 0. Внимание! Нумерация элементов файлов начинается с нуля! б) открытие существующего файла для чтения и записи в него данных: ReSet(f_int); При этом на внешнем носителе отыскивается файл с заданным именем и, если он найден, то указатель текущей записи становится в начало файла – на запись с номером 0. Запись в открытый для записи файл осуществляется оператором Write(файловая переменная, имя записываемой переменной); Например, Write(f_int, n); записать в файл f_int значение переменной n Внимание! Оператор WriteLn использовать нельзя. В этом случае значение переменной n записывается в файл на то место, где стоит указатель текущей записи. Если там была какая-то запись, то она заменяется новой. После записи указатель автоматически перемещается на следующую позицию. Если указатель перед этим находился на метке EOF в конце файла, то новая запись помещается в конец файла и файл автоматически расширяется. Из открытого для чтения файла можно прочитать все записи и вывести их, например, на экран: ReSet(f_int); открываем файл f_int для чтения пока не конец файла f_int While Not(EOF(f_int) Do Begin читаем из него очередную запись в Read(f_int,n); переменную n выводим прочитанное значение на экран Write(n:5); End; текстовый курсор – в начало новой WriteLn; строки на экране Внимание! Оператор ReadLn при чтении типизированных файлов использовать нельзя. Таким образом, типизированный файл читается с помощью цикла с предусловием While. Условие окончания цикла – чтение метки конца цикла EOF. После окончания работы с файлом он должен быть закрыт оператором: Close(файловая переменная); Например, Close(f_int); Пример записать в целочисленный файл несколько чисел, вводимых с экрана. Конец ввода – число 0. Прочитать эти числа из файла и вывести их на экран в одну строку. Интерфейс программы: Введите число: 3 Введите число: -1 Введите число: 5 Введите число: 12 Введите число: -6 Введите число: 0 Введены числа: 3 -1 5 12 -6 Программа: Program File_1; Uses CRT; Var n : Integer; f_int : File Of Integer; Begin ClrScr; Assign(f_int, ‘d:\User\f_int.dat’); ReWrite(f_int); Repeat Write(‘Введите число:’); ReadLn(n); If (n <> 0) Then Write(f_int,n); Until (n=0); ReSet(f_int); Схема алгоритма: While Not(EOF(f_int)) Do Begin начало Read(f_int, n); Write(n:5); Список данных: n – целое f_int - файл целых чисел End; WriteLn; Close(f_int); ReadLn; Открыть файл f_int для записи End. ввод n n <> 0 да запись n в f_int Открыть файл f_int для чтения нет Функции для работы с типизированными файлами Для работы с типизированными файлами используются следующие функции: FileSize(файловая переменная) - текущий размер файла – количество записей в файле, FilePos(файловая переменная) - номер текущей записи в файле – позиция указателя текущей записи (нумерация записей начинается с нуля, номер последней записи на единицу меньше текущего размера файла), и процедуры: Seek(файловая переменная, номер) - перемещение указателя на запись с заданным номером (нумерация записей начинается с нуля), Truncate(файловая переменная) - усечение файла после текущей записи: все записи в файле после текущей удаляются, и после нее ставится метка конца файла EOF, Erase(файловая переменная) - уничтожение файла – стирание его с диска. Пример: открыть файл, созданный предыдущей программой, определить его конечный размер, номер начальной записи, поставить указатель на третью запись (по номеру), вывести ее на экран, усечь файл, начиная с нее и вывести новый файл на экран: Программа: Program File_1; Uses CRT; Var n : Integer; f_int : File Of Integer; Begin ClrScr; Assign(f_int, ‘d:\User\f_int.dat’); ReSet(f_int); открываем файл для чтения While Not(EOF(f_int)) Do пока не конец файла: Begin Read(f_int, n); читаем из него в n очередную запись Write(n:5); и выводим значение n на экран End; WriteLn; n := FileSize(f_int); n – размер файла- количество записей в нем WriteLn(‘Размер файла равен ’, n); ReSet(f_int); ставим указатель на начальную запись n := FilePos(f_int); n – номер начальной записи в файле WriteLn(‘Номер начальной записи равен ’, n); Seek(f_int, 3); Read(f_int, n); ставим указатель на запись с номером 3 читаем из файла в переменную n текущую запись WriteLn(‘Запись с номером 3 равна ’, n); Truncate(f_int); удаляем из файла все записи после текущей ReSet(f_int); открываем файл для чтения - ставим указатель на начальную запись While Not(EOF(f_int)) Do снова читаем файл и выводим его на экран Begin Read(f_int, n); Write(n:5); End; WriteLn; закрываем файл Close(f_int); ReadLn; End. На экран будет выведено: 3 -1 5 12 -6 Размер файла равен 5 Номер начальной записи равен 0 Запись с номером 3 равна 12 3 -1 5 12