Технология работы с файлами в системе Delphi требует определённого порядка действий:

  1. Прежде всего файл должен быть открыт . Система следит, чтобы другие приложения не мешали работе с файлом . При этом определяется, в каком режиме открывается файл - для изменения или только считывания информации. После открытия файла в программу возвращается его идентификатор, который будет использоваться для указания на этот файл во всех процедурах обработки.
  2. Начинается работа с файлом . Это могут быть запись, считывание, поиск и другие операции.
  3. Файл закрывается. Теперь он опять доступен другим приложениям без ограничений. Закрытие файла гарантирует, что все внесённые изменения будут сохранены, так как для увеличения скорости работы изменения предварительно сохраняются в специальных буферах операционной системы.
В Delphi реализовано несколько способов работы с файлами . Познакомимся со классическим способом, связанным с использованием файловых переменных . Файловая переменная вводится для указания на файл. Делается это с помощью ключевого слова File :

Var F: File ;

Описанная таким образом файловая переменная считается нетипизированной , и позволяет работать с файлами с неизвестной структурой. Данные считываются и записываются побайтно блоками, размер которых указывается при открытии файла, вплоть от 1 байт.

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

Var F: File of тип_записи ;

В качестве типа могут использоваться базовае типы, или создаваться свои. Важно только, чтобы для типа был точно известен фиксированный размер в байтах, поэтому, например, тип String в чистом виде применяться не может, а только в виде String[N] , как указывалось в уроке Delphi 5 .

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

Для текстовых файлов отдельно укажу, что тип файловой переменной в этом случае TextFile , а тип обычной - String .

Для открытия файла нужно указать, где он расположен. Для этого файловая переменная должна быть ассоциирована с нужным файлом, который определяется его адресом. Адрес файла может быть абсолютным, с указанием диска и каталогов ("C:\Мои документы\Мои рисунки\FileName.ini"), или относительным, тогда он создаётся в папке с .exe файлом программы. Для задания относительного адреса достаточно указать имя файла с нужным расширением. Делается это оператором AssignFile:

AssignFile(SaveF, "C:\Мои документы\Мои рисунки\FileName.ini");
AssignFile(SaveF, "FileName.ini");

Теперь файл должен быть открыт.
Открытие файла оператором 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 (аббревиатура E nd O f F ile), который равен 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 ;

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


1) Направление выходного потока вашей программы в файл.
2) Направление выходного потока вашей программы на принтер.
3) Чтение из входного файла.

Направление выходного потока вашей программы в файл

Часто мои профессора, чтобы убедиться в моей честности и поверить в то, что программа создана моими руками, требуют ее полный листинг или упоминания обо мне в качестве одного из авторов. Далее они хотят, чтобы все генерируемые программой данные выводились в файл. Но как это сделать на Delphi или на простом Паскале???

Просто в Delphi ....


Направление выходного потока вашей программы на принтер

В некоторых случаях может возникнуть необходимость печатать генерируемые программой данные непосредственно на принтер. Вот как это можно сделать:


Чтение из входного файла

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


В Паскале...


{НАЧАЛО INFILE.TXT} 2 Здравствуй, мир Моя программа работает, и этот текст доказательство этому. {КОНЕЦ INFILE.TXT} Для получения дополнительной информации обратитесь к Руководству Разработчика. Ознакомьтесь с описанием функций AssignFile, Assign, Reset, Rewrite, readln, writeln, Close, CloseFile.

Файл – это именованная структура данных, представляющая собой последовательность элементов данных одного типа расположенных на диске или любом другом внешнем носителе.

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

В зависимости от типа элементов различают три вида файла:

– файл из элементов определенного типа (типизированные файлы);

– файл из элементов, тип которых не указан (нетипизированный файл);

– текстовый файл, т.е. элементами являются текстовые строки.

Для работы с файлом в программе объявляется файловая переменная (логический файл) в разделе описания переменных:

имя_файла: file of тип_элементов_файлов;

Файл, компонентами которого являются данные символьного типа, называется символьным, или текстовым:

имя_файла: TextFile;

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

AssignFile(var f, имя_файла: String);

Функции и процедуры для работы с файлами:

1. Открытие файла для записи

– перезапись (запись нового файла поверх существующего или создание нового файла) – используется процедура

rewrite (файловая_переменная)

– добавление в конец файла – используется процедура

append (файловая_переменная)

1. Запись в файл

Write

Writeln (файловая_переменная, список_переменных)

Различие между инструкциями в том, что инструкция writeln после вывода всех значений, записывает в файл символ «новая строка».

2. Закрытие файла. Перед завершением работы все открытые файлы необходимо закрыть с помощью процедуры

CloseFile (файловая_переменная)

3. Открытие файла для чтения. Используется процедура Reset(файловая_переменная)

4. Чтение данных из файла

read (файловая_переменная, список_переменных)

readln (файловая_переменная, список_переменных)

Отличие между этими процедурами в том, что при вызове инструкции readln указатель чтения из файла автоматически перемещается в начало следующей строки файла.

5. Определение конца файла. Используется функция EOF (файловая_переменная). Значение функции равно false, если прочитанный элемент данных не является последним в файле, т.е. возможно дальнейшее чтение. Если прочитанный элемент файла является последним, то значение EOF равно true.

While not eof(f) do begin … end;

6. Rename (var F; NewName: string) – переименовывает неоткрытый файл F любого типа. Новое имя задается в NewName.

7. Seek ( var F; NumRec: Longint) – устанавливает позицию чтения-записи на элемент с номером NumRec; F – типизированный или нетипизированный файл.

8. IOResult : Integ er – возвращает код, характеризующий результат (была ошибка или нет) последней операции ввода-вывода.

9. FilePos (var F): Longint – возвращает для файла F текущую файловую позицию (номер элемента, на которую она установлена, считая от нуля). Не используется с текстовыми файлами.

10. FileSize (var F): Longint – возвращает число компонент в файле F. Не используется с текстовыми файлами.

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

– {SITELINK-S102}OpenDialog{/SITELINK};

– {SITELINK-S103}SaveDialog{/SITELINK} и др, которые находятся на вкладке Dialogs.

Мы подробно рассмотрим, как копировать, удалять, переименовывать файлы. Научимся считывать и записывать информацию в типизированные файлы.

Копирование файлов с помощью .

Для этого нам потребуется вызов всего одной функции, которая выполняет именно копирование файлов. Это функция CopyFile(). У нее три параметра, два из которых обязательны. Вот полный синтаксис.
CopyFile("путь до начального файла","Путь куда надо копировать",Перезаписывать или нет)

Пример: CopyFile("D:sekretBD.txt","C: ame.txt", true);

В первом параметре можно указывать не только полный путь до файла. Если укажем, например, такой путь "sekretBD.txt", то наша программа будет искать этот файл в своем каталоге. Имя и разрешение нужно указывать именно такими, какие они есть у файла, иначе программа просто не найдет файл.
Во втором параметре тоже можно указывать относительный путь и там вы можете указать имя и расширение файла такое, какое захотите. Т.е. с помощью этой функции можно делать и переименовывание тоже.
Третий параметр отвечает за перезапись файла. Если мы укажем true, то файл не будет перезаписан, а если false, то программа перезапишет файл.

Переименование файлов с помощью

За переименование файлов отвечает функция RenameFile(). У нее 2 параметра. Вот ее полный синтаксис
RenameFile("путь до файла","новое имя");
Честно говоря, синтаксис этой функции меня не особо радует. В нем тоже в обоих параметрах надо указывать полный путь. Т.е. если мы, например, напишем так

RenameFile("C:2.txt","3.txt");

То он скопирует файл в каталог программы. Т.е. получается, что она может выполнять роль копирования тоже. Это немного странно.

Удаление файлов с помощью

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

DeleteFile("C:myprofile.txt");

Единственное, что она не всегда 100% удаляет файл. Когда файл защищен, она его не сможет удалить.

Работа с типизированными файлами в

Что такое типизированный файл? Это файл с определенной структурой. Обычно это структурой выступают записи и базовые типы. В общем, важно, чтобы у типа был известен фиксированный размер, поэтому тип string применять нельзя, нужно делать так: String[N].
Вначале нам нужно объявить переменную, где будут храниться данные из файла. Делается это так:

Var f: file of <Тип>
Например, f: file of string;

Затем нам нужно соединиться с файлом. Для этого есть команда AssignFile. Для вызова надо прописать два параметра, это переменная, которую мы объявили выше и путь до файла. Например

AssignFile(f,"C:delphi.ini");

Теперь файл нужно открыть. Можно открыть двумя способами: с перезатиранием и без. Метод Rewrite открывает файл, предварительно создав его. Т.е. если файла в указанном нами пути не будет находиться, то он его создаст. Если там уже был такой файл, то он будет удален и заново создастся чистый файл. Метод Reset открывает файл и ставит указатель в самое начало файла. Но этот метод опасен тем, что если файла, указанного в подключении, нет, то программа вылетит с ошибкой. Так что для правильного применения функции Reset надо сказать компилятору об отключении ошибок. Задается это директивой {$I-} т.е. полный синтаксис функции reset будет таким:

{$I-}
Reset(f);
{$I+}

После этого надо проверить, был ли открыт файл или нет. Это можно сделать с помощью функции IOResult. Если она не равна нолю, то все успешно.
Полный синтаксис:

{$I-}
Reset(f);
{$I+}
If IOresult <> 0 then <ваш код>

Также осуществить проверку поможет функция FileExists. В ней нужно указать путь до файла.
Для чтения файла служит функция Read(), в которой указываются два параметра: переменная файла и тип записи, в нашем случае это string. Синтаксис:

Для записи в файл служит функция Write(), в которой указываются такие же два параметра: переменная файла и тип записи, в нашем случае это string. Синтаксис:

While not eof(f) do
Read(f,String);

Также есть функция seek, с помощью которой мы можем перейти на интересующую нас запись. Например, нам нужно обратиться к 20 записи и мы делаем так:

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

После выполнения всех операций с файлом, необходимо его закрыть с помощью функции CloseFile(f);
Вот и все. На этом урок закончен. До встречи на сайте!

Урок 15. Работа с файлами

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

Как известно, файлы имеют различные форматы и к ним применяются различные программы для обработки. Например, файлы рисунков BMP, текстовые файлы TXT и т.п. Файлы имеют различные имена и определенное расширение, имеющее в среде MS-DOS максимально три символа. Если у файла расширение RAR, то пользователь и операционная система знает, что это архиватор, причем windosw для обработки этого файла применяет средства, указанные в специальном разделе реестра.

Копирование файлов

Для копирования файлов применяется функция CopyFile. Формат ее такой:

CopyFile(Исходный_файл,Записуемый_файл,Флаг_перезаписи);

где: Исходный_файл – полный путь и название файла, который копируется;

Записуемый_файл – полный путь и название файла, куда копируется исходный файл;

Флаг_перезаписи – будет или нет перезаписан файл, если таковой уже существует (true - не будет, false - будет перезаписан).

CopyFile является функцией, которая возвращает флаг успешной или нет операции копирования.

Например, следующая строка:

if not CopyFile("c:\command.com","c:\1.com",true) then ShowMessage("Ошибка копирования");

скопирует файл command.com в файл 1.com только в том случае, если последнего нет, в противном случае будет выдаваться сообщение об ошибке копирования.

Перемещение файлов

Для перемещения файлов применяется функция MoveFile. Она имеет следующий формат:

MoveFile(Исходный_файл,Записуемый_файл);

Ее параметры аналогичны вышерассмотренной команде за исключением отсутствия флага перезаписи.

if not MoveFile("c:\1.com","c:\2.com") then ShowMessage("Ошибка перемещения");

Переименование файлов

Функция RenameFile

if not RenameFile("c:\2.com","c:\3.com") then ShowMessage("Ошибка переименования");

У всех вышесказанных командах параметры исходного и конечного файла имеет тип PChar. Это строковый тип с завершающимся нулем. Возможно, вы раньше слышали о таком формате строковых данных. В такую переменную можно занести строку очень большой длины. Ее размер ограничивается наличием нулевого байта в конце. Теоретически такая переменная может иметь бесконечный размер. На практике она ограничивается размерами выделяемой памяти для программы (2Гб).

Преобразование обычной строковой переменной, типа String в PChar производится функцией:

PChar(Строковая_переменная).

При этом, для команд файловых операций возможны объединение строк. Например:

procedure TForm1.Button1Click(Sender: TObject);

Var InDir,OutDir:String; // объявление строковых переменных

begin

InDir:="c:\1\"; // каталог исходных файлов

OutDir:="c:\2\"; // каталог записуемых файлов

CopyFile(PChar(InDir+"1.txt"),PChar(OutDir+"1.txt"),false);

CopyFile(PChar(InDir+"2.txt"),PChar(OutDir+"2.txt"),false);

end;

Здесь налицо операция соединения двух строковых переменных.

В итоге этой процедуры будет копирование файлов c:\1\1.txt и c:\1\2.txt в каталог c:\2. Файлы копируются под теми же именами.

Удаление файлов

Функция DeleteFile

if not DeleteFile("c:\3.com") then ShowMessage("Ошибка удаления");

Работа с текстовыми файлами. Чтение из текстового файла

На прошлых уроках мы как, в компоненте Memo процесс загрузки и записи текстового файла делался следующим образом:

Memo1.Lines.SaveToFile(Имя_файла); // сохранение

Все это благодаря свойству Lines, в котором хранятся строки.

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

procedureTForm1.Button1Click(Sender: TObject);

Varf:TextFile; // объявление файловой переменной

st:String ; // строковая переменная

begin

AssignFile(f,"c:\1.txt"); // привязка названия файла к файловой переменной

{$I-} // отключение контроля ошибок ввода-вывода

Reset(f); // открытие файла для чтения

{$I+} // включение контроля ошибок ввода-вывода

ifIOResult<>0 then // если есть ошибка открытия, то

begin

ShowMessage("Ошибка открытия файла C:\1.TXT");

Exit; // выход из процедуры при ошибке открытия файла

end ;

While not EOF(f) do // пока не конец файла делать цикл:

begin

ShowMessage(st); // выводить строку пользователю

end ;

CloseFile(f); // закрыть файл

end;

Прокомментирую некоторые строки этого примера.

Команда AssignFile осуществляет привязку строки пути файла к файловой переменной. Все дальнейшие операции с файловой переменной автоматически осуществляются с указанным файлом. Для избежания путаниц, указывайте полный путь к файлу.

{$I-} и {$I+} являются директивами компилятору, что в этом месту соответственно следует отключить и включить контроль ошибок ввода-вывода. В данном случае при неудачной попытке открытия файла c:\1.txt (файл отсутствует или открыт для записи другой программой) наша программа не выдаст аварийной ошибки и продолжит выполнение данной процедуры. Это свойство полезно для обработки всех возможных случаев в работе программы.

IOResult – переменная, которая хранит в себе код ошибки последней операции ввода-вывода. Если она равна нулю, то последняя операция была успешно выполнена.

EOF(Файл) – функция, возвращающая признак конца файла. Т.е. она показывает, достигнут или нет конец открытого файла.

ReadLn(Файл,Переменная) – процедура считывания переменной из файла. В отличие от команды Read производит считывание строки с завершающимся символом перевода строки под кодами 13 и 10 (клавиша Enter).

CloseFile(Файл) – процедура закрытия ранее открытого файла.

Работа с текстовыми файлами. Запись в текстовый файл

Рассмотрим пример:

procedure TForm1.Button1Click(Sender: TObject);

Var f:TextFile; // указатель на текстовый файл

AssignFile(f,"c:\1.txt"); // привязка названия к переменной

Append(f); // открыть файл для добавления

if IOResult<>0 then // если ошибка открытия (напр. файла нет)

Rewrite(f); // создать новый файл

if IOResult<>0 then // ошибка создания файла

ShowMessage("Ошибка создания файла C:\1.TXT");

WriteLn(f,"Привет"); // запись в файл строки с символами перевода строки

CloseFile(f); // закрыть файл

Процедура Append(Файл) открывает файл для записи и устанавливает указатель записи в конец файла, т.е. все добавляемые к файлу строки будут записаны в конец файла.

В нашем случае в самом начале файла 1.txt может не оказаться на диске, поэтому команда открытия файла для добавления вызовет ошибку. В этом случае срабатывает наш собственный контроль ошибок и выполняется команда создания файла.

Запись и чтение из файла не текстовых данных

Рассмотрим пример, в котором программа при выходе сохраняет свои размеры и положение окна на экране в файл и при последующем запуске восстанавливает состояние, которое было при выходе. Программа состоит из двух процедур OnShow и OnClose для окна Form1 программы.

procedure TForm1.FormShow(Sender: TObject);

Var f:file of Integer; // файловая переменная, тип integer

I:Integer; // целочистенная переменная

begin

AssignFile(f,"pos.ini");

{$I-}

Reset(f);

{$I+}

if IOResult<>0 then Exit;

Form1.Top:=i; // верхнее положение окна

Read(f,i);

Form1.Left:=i; // левое положение окна

Read(f,i);

Form1.Width:=i; // ширина окна

Read(f,i);

Form1.Height:=i; // высота окна

CloseFile(f);

end ;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

Var f:file of Integer;