Файлы
Lazarus IDE: Основы программирования в Windows
Несмотря на то, что всё потихоньку уходит в сеть, программирование для настольных компьютеров остаётся востребованным. И будет таковым ещё долго. Ну а самая распространённая операционная система для настольных компьютеров – это по-прежнему Windows. Поэтому любой программист, даже если он собирается стать веб-разработчиком, должен знать хотя бы основы создания программ для Windows. Подробнее... |
Наверняка вы уже задавались вопросом, как сохранить какие-то данные программы на диске, а потом прочитать их. Очень часто в файлах хранятся разные настройки программы. На первых этапах файлы также можно использовать для обмена данными между программами.
Вообще работа с файлами - это огромная тема. Этому можно посвятить отдельную книгу. Но новичкам слишком много информации знать не нужно, так как ничего кроме путаницы в голове это не вызовет. Поэтому здесь мы ограничимся лишь краткими сведениями о работе с файлами на примере языка Паскаль.
Итак, начнём с того, что понятие файл в Паскале имеет дав смысла:
- Это информация на внешнем устройстве (то есть обычный файл на диске) - внешний файл.
- И это переменная файлового типа - внутренний файл.
Чтобы начать работать с внешним файлом, нужно установить связь между внутренним и внешним файлом. И тогда, всё что будет происходить с внутренним файлом, будет также происходить и с внешним файлом.
Говоря по простому, для того, чтобы начать работать с файлом в вашей программе, нужно
связать с внешним файлом файловую переменную
Делается это так. Сначала объявляем файловую переменную:
iFile : file of integer;
Теперь с этой переменной можно работать. Например, так:
Assign(iFile, 'ifile.txt'); //Связать переменную с файлом Rewrite(iFile); //Открыть файл для записи Write(iFile, 100); //Записать в файл число 100 Close(iFile); //Закрыть файл
Здесь мы связываем объявленную ранее файловую переменную iFile с реальным файлом на диске. Этого файла на диске может и не быть, но имя файла должно быть правильным именем файла, допустимым в операционной системе, для которой создаётся программа.
Далее мы открываем файл для записи, а затем записываем в него число 100.
После завершения работы с файлом его нужно обязательно закрыть. Иначе могут возникнуть утечки памяти и другие проблемы.
Функция Rewrite не только открывает файл для записи, но и создаёт его, если этого файла раньше не было. Если файл был, то он будет перезаписан. Поэтому будьте внимательны. По идее, надо сначала проверить существование файла, и только потом принимать решения, что делать дальше.
В нашем примере мы создаём файл с именем iFile.txt в той же папке, откуда была запущена программа. Если нужно создать файл в другом месте, то нужно указывать полный путь к файлу. Если вы не знаете, что такое полный путь к файлу, то рекомендую прочитать книгу Компьютер для чайника.
После этих манипуляций появится новый файл с указанным именем и там будет записано число 100. Вы можете открыть этот файл и посмотреть. Возможно, вас удивит, что в файле будет записана одна буква d. Но всё объясняется просто. Обычный текстовый редактор не может работать с двоичными данными. Поэтому он воспринимает число 100 как букву (100 - это ASCII-код латинской буквы d).
Если вы откроете этот файл с помощью шестнадцатеричного редактора, то вы увидите число 64, а не 100. И здесь тоже всё просто - шестнадцатеричный редактор отображает числа в шестнадцатеричном формате. А 64 в шестнадцатеричной системе - это 100 в десятичной системе.
Итак, мы умеем создавать файлы и записывать в них информацию. Теперь научимся читать файл.
Assign(iFile, 'ifile.txt'); //Связать переменную с файлом Reset(iFile); //Открыть файл для чтения Read(iFile, i); //Прочитать данные из файла в i Close(iFile); //Закрыть файл
Открываем файл с помощью функции Reset. Читаем данные из файла с помощью функции Read и сохраняем их в переменной i.
Файл должен существовать по указанному пути, иначе возникнет ошибка времени выполнения программы.
Идём дальше.
Записывать в файл всего одно число конечно можно. А иногда этого вполне достаточно. Однако может возникнуть необходимость записать несколько однотипных чисел. Сделать это можно так:
Assign(iFile, 'ifiles.txt'); //Связать переменную с файлом Rewrite(iFile); //Открыть файл для записи for i := 0 to 15 do //Записать в файл 16 чисел Write(iFile, i); //от 0 до 15 Close(iFile); //Закрыть файл
Прочитать такой файл можно так:
Reset(iFile); //Открыть файл для чтения for i := 0 to 15 do //Прочитать из файла begin Read(iFile, j); //первые 16 чисел Write(j, ' '); //и вывести на экран end; Close(iFile); //Закрыть файл
Если при чтении файла с несколькими значениями вы попытаетесь прочитать больше чисел, чем записано в файле, то это приведёт к ошибке во время выполнения программы. Поэтому читать файлы таким образом можно только тогда, когда вы точно знаете, сколько значений хранится в файле.
Но как быть, если вам не нужно читать все значения? Как получить доступ к конкретному значению в файле?
Есть специальная функция, которая может переместить указатель файла в любое его место.
Reset(iFile); //Открыть файл для чтения Seek(iFile, 8); //Переместить указатель на 8-ю позицию Read(iFile, j); //Прочитать число 8-й позиции Write(j); //Вывести на экран Close(iFile); //Закрыть файл
Функция Seek перемещает указать на заданную позицию. Обратите внимание, что в нашем примере мы начинаем отсчёт с нуля, поэтому 8-я позиция содержит число 8, хотя фактически это 9-е число в файле.
Тип файловой переменной может быть любым, кроме файлового. В том числе пользовательским. Это означает, что вы можете хранить в файле сложные структуры данных, такие как записи, массивы и т.п.
Это, в свою очередь, означает, что вы таким образом можете сохранять в файлах (а затем читать), например, какие-то настройки программы.
Файловые переменные могут быть типизированными или нетипизированными. Типизированная файловая переменная - это файл с данными какого-то типа. Нетипизированная файловая переменная - это просто текстовый файл, который содержит какие-то произвольные данные. С таким файлом надо работать немного по другому.
Объявляется нетипизированная файловая переменная, например, так:
nFile : Text;
Записать данные в файл можно так:
Assign(nFile, 'nfile.txt'); //Связать переменную с файлом Rewrite(nFile); //Открыть файл для записи for i := 1 to 8 do //Записать в файл 8 строк WriteLn(nFile, i); Close(nFile);
Обратите внимание, что здесь мы используем функцию WriteLn, для того, чтобы записывать каждое число с новой строки. Разумеется, можно использовать и Write, но тогда всё будет записано в одну строку, а в некоторых случаях это неудобно.
Теперь прочитаем все строки файла и выведем их на экран.
Reset(nFile); //Открыть файл для чтения while not Eof(nFile) do //Пока не закончится файл begin ReadLn(nFile, str); //Читать строку WriteLn(str); //и выводить на экран end;
Перед тем, как использовать этот пример, надо объявить переменную str строкового типа.
Затем открываем файл для чтения, читаем каждую его строку и выводим на экран.
Поскольку мы можем не знать, сколько строк имеется в файле, то мы используем функцию Eof, которая возвращает TRUE, когда достигнут конец файла.
Есть ещё один момент, который может оказаться вам полезным. Если вам не нужно полностью перезаписывать файл, а достаточно добавить только одну строку, то можно использовать функцию Append, которая открывает файл для добавления данных. При этом все старые данные сохраняются, а новые данные добавляются в конец файла. Пример:
Append(nFile); //Открыть файл для добавления WriteLn(nFile, '100'); //Добавить новую строку Close(nFile); //Закрыть файл
Обратите внимание, что функция Append сама открывает файл, то есть перед её использованием файл должен быть закрыт.
Ну что же, на этом остановимся, дабы не перегружать начинающих избыточной информацией. Для многих случаев этих знаний о работе с файлами вам будет вполне достаточно. Во всяком случае на начальном этапе обучения программированию.