Работа с файлами


Файловая система

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

          Файл - это некое количество информации, которое имеет имя и хранится в долговременной памяти, то есть, на жёстком диске или на каких-либо других носителях. В файлах могут содержаться тексты, изображения, звуки, бла, бла, бла, бла, бла... Думаю, Вы это и без меня знали. Так вот. Нас интерисуют только программы, написанные на бейсике и паскале, а также данные для этих программ. Как сохранять программы, Вы тоже знаете.

          Разберёмся с доступом к файлам и операциями над ними.

Вверх

Способы доступа к файлам

          Существуют два метода доступа к файлам - последовательный и прямой доступ. Файлы оследовательного доступа наиболее просты как в организации, так и в работе с ними. Записи (запись - это набор данных о каком-либо одном объекте) обрабатываются последовательно одна за другой. Информация о таких файлах хранится в виде текста в кодах ASCII. Подобные файлы легко просмотреть на экране, итспользуя любой простейший редактор, или в самом бейсике или паскале. Но, как всегда, у каждой медали две стороны. Простота - хорошо, а последовательность в данном случае - плохо. Если информация об интересующих меня объектах упорядочена в файле по алфавиту, то всякий раз мне придётся перебирать практически весь файл , чтобы добраться до нужной записи. Отсюда, при большом информационном объёме файла обработка его резко замедляется.

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

!

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

Вверх

Операции над файлами

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

!

Почему-то нельзя одновременно пытаться читать и записывать в открытый файл. Сначала надо открыть файл для чтения, прочитать нужную информацию, обработать её и закрыть файл. Потом открыть файл для записи, записать туда результаты обработки и закрыть файл.

Вверх

Бейсик: открытие файла

          Для открытия файла предназначен оператор OPEN, имеющий следующий формат:

          OPEN имя_файла FOR режим AS # номер_файла

          С именем файла должно быть всё понятно. Режим определяет доступ к данным файла. Возможны следующие режимы:

  • INPUT - режим чтения информации из файла. В случае, если указывается несуществующее имя файла, возникает сообщение об ошибке "Файл не найден".
  • OUTPUT - режим записи информации в файл. Обычно при этом создаётся новый файл. Если же открывается для записи уже существующий файл ,то ранее хранимая в нём информация будет безвозвратно утеряна.
  • APPEND - режим добавления информации в файл. Новая информация будет размещена в конце файла, за последней записью.

          Номер файла - число от 1 до 255, сопровождается необязательным знаком #.

Вверх

Бейсик: запись в файл

          Рассмотрим пример записи в файл:

          В результате работы программы в файл Strings.dat запишется пять введённых с клавиатуры строковых выражений. Причём, если такого файла в папке нет (папка, кстати, по умолчанию - это папка самого бейсика или паскаля), то программа создаёт его. Кстати да! Как мы видим, имя файла в кавычках - хначит можно вводить имя файла как строковую переменную.

          Каждый новый файл нужно называть новым именем - номером от 1 до 255.

!

Вообще не рекомендуется открывать одновременно несколько файлов. Открыли, поработали с файлом - закройте.

          Вот ещё - запись в файл может осуществляться как оператором PRINT, так и оператором WRITE - результат будет совершенно одинаковым. "PRINT/WRITE #номер_файла, выражение" - вот так.

Вверх

Бейсик: чтение из файла

          Чтение из файла осуществляется практически так же, как и запись, но вместо OUTPUT'а используется INPUT.

          Разберём на примере. Допустим, у нас есть файл, в котором три строки, в каждой - по числу. И нам надо вычислить сумму этих чисел. Файл называется count.dat. Смотрим.

          Ничего такого необычного - очистка экрана, открытие файла для чтения, затем считывание трёх переменных, а потом - занесение в новую переменную их суммы, после чего - вывод этой переменной на экран. Всё просто. Теперь Вы можете сохранять и читать какую-либо информацию во время выполнения своих программ. К примеру, можно сделать сохранение и загрузку игры. А что, хорошая мысль! (:

          Кстати, ещё два оператора: KILL имя_файла - удаляет файл, NAME имя_файла_1 AS имя_файла_2 - изменяет имя файла 1 на имя 2, то есть, переименовывает. Ах да! Если внезапно программа наткнулась на конец файла и не может дальше читать, то существует условие "EOF(номер_файла)" (EOF - End Of File - конец файла) - можно создать цикл DO, а после слова LOOP поставить UNTIL EOF(#1), а в цикле - ввод переменных из файла.

Вверх

Бейсик: добавление данных в файл

          Абсолютно аналогично предыдущим двум разделам, только все вводимые данные добавляются в файл. Вместо INPUT и OUTPUT - APPEND. Ничего сложного - информация просто дописывается в конец открытого файла. Думаю, даже пример не надо показывать, думаю, сами разберётесь. Теперь давайте посмотрим на всё это дело со стороны паскаля.
Вверх

Паскаль: типы файлов

          Паскаль "понимает" три файловых типа:
  • текстовые файлы;
  • типизированные файлы;
  • нетипизированные файлы.

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

  • text - текстовые файлы;
  • file of тип_файла - типизированные файлы;
  • file - нетипизированные файлы.

          Понятное дело - описываются они в блоке описания переменных. Например: Var f1:File of Char; f2:File of Integer; f3:File; t:Text;

Вверх

Паскаль: стандартные процедуры и функции с файлами

          Все файлы, с которыми работает паскаль во время выполнения Вашей программы, согласуются с переменными файлового типа.
  • Assign(переменная, имя_файла) - связывает переменную с физическим файлом. После этой строки вся работа с файлом будет проходить с переменной, которая связывается с этим файлом. То есть, эта переменная является как бы ссылкой на файл. Понятно? Установленная связь будет действовать до конца программы или до нового переназначения.После связи файловой переменной с дисковым именем файла в программе нужно указать направление передачи данных (открыть файл). В зависимости от этого направления говорят о чтении из файла или записи в файл.
  • Reset(f) - открывает файл, с которым связана переменная f, для чтения. Если f - типизированный файл, то процедура Reset открывает файл для чтения и записи одновременно (аналог в бейсике - OPEN...OUTPUT...).
  • Rewrite(f) - открывает файл, с которым связана переменная f, для записи. Если названный файл уже существует, то все данные из него стираются (аналог в бейсике - OPEN...INPUT...).
  • Close(f) - закрывает открытый ранее файл f (аналог в бейсике - CLOSE #номер_файла).
  • Rename(f,новое_имя) - переименовывает файл переменной f (аналог в бейсике - NAME имя_файла AS новое_имя).
  • Erase(f) - стирает файл, с которым была связана переменная f (аналог в бейсике - KILL файл). При этом этот файл должен быть закрыт.
Вверх

Паскаль: работа с типизированными файлами

          Типизированный файл - это последовательность компонент любого заданного типа (кроме типа "файл"). Доступ к компонентам файла осуществляется по их порядковым номерам. Компоненты нумеруются, начиная с 0. После открытия файла указатель (номер текущей компоненты) стоит в его начале на нулевом компоненте. После каждого чтения или записи указатель сдвигается к следующему компоненту.
  • Write(f, выражение); - запись в файл. Аналог в бейсике - PRINT #номер_файла, выражение.
  • Read(f, список_переменных); - процедура читает из файла f компоненты в указанные переменные. Тип файловых компонент и переменных должны совпадать. Если будет сделана попытка чтения несуществующих компонент, то произойдет ошибочное завершение программы. Необходимо либо точно рассчитывать количество компонент, либо перед каждым чтением данных делать проверку их существования (функция eof, см. выше). Аналог в бейсике - INPUT #номер_переменной, список_переменных.
  • Seak(f,n); - смещение курсора в файле на n-ю позицию. Нумерация начинается с 0. В бейсике аналогов, кажется, нет.
  • FileSize(f):LongInt; - возвращает количество компонент в файле.
  • FilePos(f): longint; - Функция возвращает порядковый номер текущего компонента файла f.
  • Truncate(f); - процедура отсекает конец файла, начиная с текущей позиции включительно.
Вверх

Паскаль: работа с текстовыми файлами

          Текстовый файл - это совокупность строк, разделенных метками конца строки. Сам файл заканчивается меткой конца файла. Доступ к каждой строке возможен лишь последовательно, начиная с первой. Одновременная запись и чтение запрещены.
  • Read(f, список переменных); ReadLn(f, список переменных); - Процедуры читают информацию из файла f в переменные. Способ чтения зависит от типа переменных, стоящих в списке. В переменную char помещаются символы из файла. В числовую переменную: пропускаются символы-разделители, начальные пробелы и считывается значение числа до появления следующего разделителя. В переменную типа string помещается количество символов, равное длине строки, но только в том случае, если раньше не встретились символы конца строки или конца файла. Отличие ReadLn от Read в том, что в нем после прочтения данных пропускаются все оставшиеся символы в данной строке, включая метку конца строки. Если список переменных отсутствует, то процедура ReadLn(f) пропускает строку при чтении текстового файла.
  • Write(f, список переменных);WriteLn(f, список переменных); - Процедуры записывают информацию в текстовый файл. Способ записи зависит от типа переменных в списке (как и при выводе на экран). Учитывается формат вывода. WriteLn от Write отличается тем, что после записи всех значений из переменных записывает еще и метку конца строки (формируется законченная строка файла).
  • Append(f) - Процедура открывает текстовый файл для добавления информации к его концу. Используйте эту процедуру вместо Rewrite.
Вверх

Паскаль: работа с нетипизированными файлами

          Нетипизированные файлы - это последовательность компонент произвольного типа.
  • Reset(f, BufSize) и Rewrite(f, BufSize) - открытие нетипизированного файла. Параметр BufSize задает число байтов, считываемых из файла или записываемых в него за одно обращение. Минимальное значение BufSize - 1 байт, максимальное - 64 К байт. Если BufSize не указан, то по умолчанию он принимается равным 128.
  • BlockRead(f, X, Count, QuantBlock); - чтение данных из нетипизированного файла. Эта процедура осуществляет за одно обращение чтение в переменную X количества блоков, заданное параметром Count, при этом длина блока равна длине буфера. Значение Count не может быть меньше 1. За одно обращение нельзя прочесть больше, чем 64 К байтов. Необязательный параметр QuantBlock возвращает число блоков, прочитанных текущей операцией BlockRead. В случае успешного завершения операции чтения QuantBlock = Count, в случае аварийной ситуации параметр QuantBlock будет содержать число удачно прочитанных блоков. Отсюда следует, что с помощью параметра QuantBlock можно контролировать правильность выполнения операции чтения.
  • BlockWrite(f, X, Count, QuantBlock); - запись данных в нетипизированный файл. Эта процедура осуществляет за одно обращение запись из переменной X количества блоков, заданное параметром Count, при этом длина блока равна длине буфера. Необязательный параметр QuantBlock возвращает число блоков, записанных успешно текущей операцией BlockWrite. Для нетипизированных файлов можно использовать процедуры Seek, FIlePos и FileSize, аналогично соответствующим процедурам типизированных файлов.
          Думаю, по аналогии с бейсиком, можно самостоятельно выучить эти операции с файлами в паскале.

Перейти к решению задач
Вверх

Завершение обучения (End)

          Ну что же, вот мой учебник и подошёл к концу. Точнее, подошла к концу его теоретическая часть. Дальше идут задачи, история, советы...

          Надеюсь, Вы вникли в написанное. Если Вы не знали этих языков, то, надеюсь, Вы овладели ими, а если и знали бейсик и паскаль, то хоть узнали что-то новое... Вам предстоит ещё многое узнать об этих языках, и не только об этих - ведь паскаль с бейсиком - это только начало. Главное - выучить их, а потом можно смело продвигаться дальше в изучении других языков. Бейсик с паскалем - база. Усвойте это.

          Практикуйтесь в написании программ, набивайте руку на это дело, и Вам не будет равных!

Удачи!
Вверх
Hosted by uCoz