Технология работы с файлами в системе Delphi требует определённого порядка действий:
Прежде всего файл должен быть открыт. Система следит, чтобы другие приложения не мешали работе с файлом. При этом определяется, в каком режиме открывается файл - для изменения или только считывания информации. После открытия файла в программу возвращается его идентификатор, который будет использоваться для указания на этот файл во всех процедурах обработки.
Начинается работа с файлом. Это могут быть запись, считывание, поиск и другие операции.
Файл закрывается. Теперь он опять доступен другим приложениям без ограничений. Закрытие файла
гарантирует, что все внесённые
изменения будут сохранены, так как для увеличения скорости работы
изменения предварительно сохраняются в специальных буферах операционной
системы.
В Delphi реализовано несколько способов работы с файлами. Познакомимся со классическим способом, связанным с использованием
файловых переменных. Файловая переменная вводится для указания на файл. Делается это с помощью ключевого слова File :
var F:File;
Описанная таким образом файловая переменная считается нетипизированной,
и позволяет работать
с файлами с неизвестной структурой. Данные считываются и записываются
побайтно блоками, размер которых указывается при открытии файла, вплоть
от
1 байт.
Но чаще используются файлы, состоящие из последовательности одинаковых записей. Для описания такого файла к предыдущему описанию
добавляется указание типа записи:
var F:File of тип_записи ;
В качестве типа могут использоваться базовае типы, или создаваться свои.
Важно только, чтобы для типа был точно известен фиксированный
размер в байтах, поэтому, например, тип String в чистом виде применяться не может, а только в виде String[N]
Данные, считанные из файла или записываемые в файл, содержатся в
обычной переменной, которая должна быть того же типа, что и файловая.
Поэтому
сначала в программе лично я описываю нужный тип, а затем ввожу две
переменные этого типа - файловую и обычную:
Для текстовых файлов отдельно укажу, что тип файловой переменной в этом случае TextFile, а тип обычной - String.
Для открытия файла нужно указать, где он расположен. Для этого
файловая переменная должна быть ассоциирована с нужным файлом, который
определяется его адресом. Адрес файла может быть абсолютным, с указанием
диска и каталогов ('C:\Мои документы\Мои рисунки\FileName.ini'), или
относительным, тогда он создаётся в папке с .exe файлом программы. Для задания относительного адреса достаточно указать имя файла с нужным расширением. Делается это оператором AssignFile :
Теперь файл должен быть открыт.
Открытие файла оператором Rewrite приведёт воссозданию файла заново, т.е. существующий файл будет без предупреждения
уничтожен, и на его месте будет создан новый пустой файл заданного
типа, готовый к записи данных. Если же файла не было, то он будет
создан.
Открытие файла оператором Reset откроет существующий файл к считыванию или записи данных, и его указатель будет установлен на начало файла :
Rewrite(SaveF);
Reset(SaveF);
Каждый из этих операторов может иметь второй необязательный параметр,
имеющий смысл для нетипизированных файлов, и указывающий длину записи
нетипизированного файла в байтах:
Rewrite(SaveF, 1);
Reset(SaveF, 1);
Чтение файла производится оператором Read :
Read(SaveF, SaveV);
Запись в файл производится оператором Write :
Write(SaveF, SaveV);
При этом чтение и запись производится с текущей позиции указателя, затем
указатель устанавливается на следующую запись. Можно проверить,
существует ли нужный файл, оператором FileExists :
if FileExists('FileName.ini') then Read(SaveF, SaveV);
Принудительно установить указатель на нужную запись можно оператором Seek(SaveF, N), где N - номер нужной записи, который, как и почти всё в программировании, отсчитывается от нуля:
Seek(SaveF, 49); - установка указателя на 50-ю запись.
При последовательном чтении из файла рано или поздно будет достигнут
конец файла, и при дальнейшем чтении произойдёт ошибка. Проверить, не
достигнут ли конец файла, можно оператором EOF (аббревиатура End Of File), который равен true, если прочитана последняя запись и указатель находится в конце файла:
while (not EOF(SaveF)) do
Read(SaveF, SaveV);
Для текстовых файлов вместо Read и Write используются операторы Readln и Writeln, умеющие определять конец строки.
В коментариях приведена процедура чтения текстового файла.
Оператор Truncate(SaveF) позволяет отсечь (стереть или, если хотите, удалить!) все записи файла, начиная от текущей позиции указателя, и до конца файла.
В конце работы с файлом его необходимо закрыть. Это делается оператором CloseFile(SaveF) ;
Теперь можно изменить программу из первой части урока, запоминающую своё положение на экране. Описание переменных опускаю, оно приведено на рисунке выше.
Создаём обработчик события Формы OnCreate со следующим содержимым:
procedure TForm1.FormCreate(Sender: TObject) ; begin
AssignFile(SaveF, 'Init.ini') ; if FileExists('Init.ini') then begin
Reset(SaveF) ;
Read(SaveF, SaveV) ;
Form1.Left := SaveV.X ;
Form1.Top := SaveV.Y ;
Form1.Caption:=SaveV.Caption ; //Наши переменные дополнительно сохраняют заголовок Формы! end ; end ;
Теперь необходимо создать обработчик события OnClose :
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction) ; begin
Rewrite(SaveF) ; //Нет необходимости проверять наличие файла, создадим его заново!
SaveV.X := Form1.Left ;
SaveV.Y := Form1.Top ;
SaveV.Caption := Form1.Caption ;
Write(SaveF, SaveV) ;
CloseFile(SaveF) ; end ;