понедельник, 28 июля 2008 г.

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

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

Как известно, файлы имеют различные форматы и к ним применяются различные программы для обработки. Например, файлы рисунков 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.LoadFromFile(Имя_файла); // загрузка

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

ReadLn(f,st); // читать из файла строку

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; // указатель на текстовый файл

begin

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

{$I-}

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

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

begin

{$I-}

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

{$I+}

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

begin

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

Exit;

end;

end;

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

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

end;

Процедура 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;

Read(f,i); //считать из файла значение

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;

begin

AssignFile(f,'pos.ini');

{$I-}

Rewrite(f);

{$I+}

if IOResult<>0 then Exit;

Write(f,Form1.Top);

Write(f,Form1.Left);

Write(f,Form1.Width);

Write(f,Form1.Height);

CloseFile(f);

end;

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

Комментариев нет: