Технология работы с файлами в системе Delphi требует определённого порядка действий:
Прежде всего файл должен быть открыт. Система следит, чтобы другие приложения не мешалиработе с файлом. При этом определяется, в каком режиме открывается файл - для изменения или только считывания информации. После открытия файла в программу возвращается его идентификатор, который будет использоваться для указания на этот файл во всех процедурах обработки.
Начинается работа с файлом. Это могут быть запись, считывание, поиск и другие операции.
Файл закрывается. Теперь он опять доступен другим приложениям без ограничений. Закрытие файлагарантирует, что все внесённые изменения будут сохранены, так как для увеличения скорости работы изменения предварительно сохраняются в специальных буферах операционной системы.
В Delphi реализовано несколько способов работы с файлами. Познакомимся со классическим способом, связанным с использованием файловых переменных. Файловая переменная вводится для указания на файл. Делается это с помощью ключевого слова File :
var F:File;
Описанная таким образом файловая переменная считается нетипизированной, и позволяет работать с файлами с неизвестной структурой. Данные считываются и записываются побайтно блоками, размер которых указывается при открытии файла, вплоть от 1 байт.
Но чаще используются файлы, состоящие из последовательности одинаковых записей. Для описания такого файла к предыдущему описанию добавляется указание типа записи:
var F:File of тип_записи ;
В качестве типа могут использоваться базовае типы, или создаваться свои. Важно только, чтобы для типа был точно известен фиксированный размер в байтах, поэтому, например, тип String в чистом виде применяться не может, а только в виде String[N], как указывалось в уроке Delphi 5.
Данные, считанные из файла или записываемые в файл, содержатся в обычной переменной, которая должна быть того же типа, что и файловая. Поэтому сначала в программе лично я описываю нужный тип, а затем ввожу две переменные этого типа - файловую и обычную:
Для текстовых файлов отдельно укажу, что тип файловой переменной в этом случае 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 ;
В данном случае файл считывается и записывается туда, куда мы ему указали. Но необходимо также уметь выбрать нужный файл в работающей программе. Описание этого - в третей части урока.