Файлы

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

Физический файл

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

Логический файл

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

Тип данных файл

Файл это потенциально бесконечная последовательность компонент одного и того же типа. Количество компонент в файле заранее не оговаривается.

Файловый тип можно задать одним из трех способов:

<имя> = File of <тип>;

<имя> = TextFile;

<имя> = File;

Здесь <имя> - имя файлового типа (правильный идентификатор);

File, of - зарезервированные слова (файл, из); TextFile - имя стандартного типа текстовых файлов; <тип> - любой тип Object Pascal, кроме файлов. Например:

type

Fl = File of Char;

F2 = TextFile;

F3 = File;

В зависимости от способа объявления можно выделить три вида файлов:

v типизированные файлы (задаются предложением File of ...);

v текстовые файлы (определяются типом TextFile);

v нетипизированные файлы (определяются типом File).

 В наших примерах F1 - типизированный файл, F2 - текстовый файл, F3 - нетипизированный файл. Вид файла, вообще говоря, определяет способ хранения в нем информации. Однако в Delphi нет средств контроля вида ранее созданных файлов. При объявлении уже существующих файлов программист должен сам следить за соответствием вида объявления характеру хранящихся в файле данных.

Файловые переменные

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

Var  as12: F2;

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

Var  as: file of byte;

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

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

Файл может находиться в различных состояниях:

1.      Файл закрыт.

2.      Файл открыт для чтения.

3.      Файл открыт для записи.

Установка и завершающие операции

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

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

AssignFile (<ф.п.>, <имя файла>);

Здесь <ф.п.> - файловая переменная (правильный идентификатор, объявленный в программе как переменная файлового типа);

<имя файла > - текстовое выражение, содержащее имя файла и, если это необходимо, маршрут доступа к нему.

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

Для чтения файл инициируется с помощью стандартной процедуры Reset;

Reset (<ф.п.>);

Здесь <ф. п. > - файловая переменная, связанная ранее процедурой AssignFile с уже существующим файлом.

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

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

 

Чтобы проверить, существует ли дисковый файл, можно использовать стандартную функцию FileExists, которая возвращает Truе, если указанный при обращении этой функции файл существует, и False - если не существует.

Например

begin

if FileExists(FileName) then

..... // Файл существует

else ..... // Файл не существует

end;

В Delphi разрешается обращаться к типизированным файлам, открытым процедурой Reset (т. е. для чтения информации), с помощью процедуры write (т. е. для записи информации). Такая возможность позволяет легко обновлять ранее созданные типизированные файлы и при необходимости расширять их. Для текстовых файлов, открытых процедурой Reset, нельзя использовать процедуру Write ИЛИ WriteLn.

Стандартная процедура

Rewrite (<ф.п.>);

инициирует запись информации в файл, связанный с файловой переменной <ф.п.>. Процедурой Rewrite нельзя инициировать запись информации в ранее существовавший дисковый файл: при выполнении этой процедуры старый файл (если он был) уничтожается и никаких сообщений об этом в программу не передается. Новый файл подготавливается к приему информации, и его указатель принимает значение 0.

Стандартная процедура

Append (<ф.п.>)

инициирует запись в ранее существовавший текстовый файл для его расширения, при этом указатель файла устанавливается в его конец. Процедура Append применима только к текстовым файлам, т. е. их файловая переменная должна иметь тип TextFile (см. выше). Процедурой Append нельзя инициировать запись в типизированный или нетипизированный файл. Если текстовый файл ранее уже был открыт с помощью Reset или Rewrite, использование процедуры Арpend приведет к закрытию этого файла и открытию его вновь, но уже для добавления записей.

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

Procedure AssignFile(var F; FileName:String);

Связывает файловую переменную f с именем файла FileName

function ChangeFileExt (const FileName, Extension: String):Strings;

Изменяет существующее расширение файла на расширение, заданное параметром Extension;

Procedure ChDir(Path:String);

Изменяет текущий каталог: path - строковое выражение, содержащее путь к устанавливаемому по умолчанию каталогу;

Procedure CloseFile (var F); 

Закрывает файл, однако связь файловой переменной F с именем файла, установленная ранее процедурой AssignFile, сохраняется. При создании нового или расширении старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге. Функции процедуры CloseFile выполняются автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования процедуры AssignFile

Function DateTimeToFileDate(DateTime:TDateTime): Integer;

Преобразует значение DateTime в системный формат времени создания (обновления) файла;

Function DiskFree(D: Byte): Longint;

Возвращает объем в байтах свободного пространства на указанном диске: D - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск В и т, д.). Функция возвращает значение -1, если указан номер несуществующего диска;

function DeleteFile(const FileName:String):Boolean;

Уничтожает файл с именем (и, возможно, маршрутом доступа) FileName. Возвращает True, если операция прошла успешно;

Function DiskSize(D: Byte): Longing;

Возвращает объем в байтах полного пространства на указанном диске: D - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск В и т. д.). Функция возвращает значение -1, если указан номер несуществующего диска;

Function EOF (var F): Boolean;

Тестирует конец файла и возвращает True, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении - что файл исчерпан;

Procedure Erase(var F);

Уничтожает файл f. Перед выполнением процедуры необходимо закрыть файл;

function FileAge(const FileName: String): Integer;

Для файла FileName возвращает время его последнего обновления (в системном формате) или -1, если такого файла не существует;

function ExcludeTrailingBackslash(const S: String): Strings;

Исключает из строки s замыкающий символ “\” (если этот символ не замыкает строку, возвращает S без изменения);

function ExpandUNCFileName(const FileName: String): String;

Дополняет имя файла текущим сетевым каталогом (и диском);

function ExtractFileDir(const FileName: String): Strings;

Извлекает из полного имени файла маршрут доступа к нему (без последнего символа “\”)

function ExtractFileExt(const FileName: String): Strings;

Извлекает из полного имени файла его расширение (с ведущей точкой)

function ExtractFileName(cons t Fi1eName: String): Strings;

Извлекает из полного имени файла его имя (с расширением)

function ExtractFilePath(const FileName: String): Strings;

Извлекает из полного имени файла маршрут доступа к нему (с последним символом “\”)

function ExtractRelativePath(const BaseName, DestName: String): Strings;

Извлекает из полного имени файла имя маршрута относительно DestName (промежуточные каталоги заменяются символами “..\”)

function ExtractShortPathName(const FileName: String): Strings;

Преобразует имя файла к короткому формату 8.3 для MSDOS и Windows 3-х

function FileDateToDateTime(FileDate: Integer) : TDateTime;

Преобразует системный формат FileDate времени создания файла в формат дата-время;

Function FileExists(const FileName: String): Boolean;

Возвращает True, если файл с именем (и, возможно, маршрутом доступа) FileName существует

function FileGetDate(Handle: Integer): Integers;

По заданному дескриптору файла Handle возвращает время и дату его создания в системном формате. Возвращает 0 в случае успеха или код ошибки

function FileSetDate(Handle: Integer; Age:

Integer): Integers;

Для файла с дескриптором Handle устанавливает новое время и дату его создания Age в системном формате.Возвращает 0 в случае успеха или код ошибки

Function FindFirst(const Path: String; Attr: Integer; var F: TSearchRec): Integer;

Возвращает атрибуты первого из файлов, зарегистрированных в указанном каталоге: Path - маршрут поиска и маска выбора файлов; Attr – атрибуты выбираемых файлов; f - переменная типа TSesrchRec, в которой будет возвращено имя первого выбранного файла. При успешном поиске возвращает значение 0

 

Procedure FindClose(var F: TSearchRec);

Освобождает память, выделенную для поиска файлов функциями FindFirst/FindNext

Function FindNext(var F: TSearchRec): Integer;

Возвращает в переменой f имя следующего файла в каталоге. Переменная f должна предварительно инициироваться обращением к функции FindFirst. При успешном поиске возвращает значение 0

Procedure Flush(varF);

Очищает внутренний буфер файла и, таким образом, гарантирует сохранность всех последних изменений файла на диске

Procedure GetDir(D: Byte; var S: Strings)

 

 

Возвращает имя текущего каталога (каталога по умолчанию): D - номер устройства (0 - устройство по умолчанию, 1 - диск А, 2- диск В и т. д.); s - переменная типа String, в которой возвращается путь к текущему каталогу на указанном диске

function IncludeTrailingBackslash(const S:String): String;

Возвращает полный маршрут доступа к файлу с ведомым символом “\”

Function lOResult: Integer;

Возвращает условный признак последней операции ввода-вывода

function IsPathDelimiter(const S: String; Index: Integer): Boolean;

Возвращает True, если в строке S символ index есть “\”.

function MatchesMask (const Filename, Mask: String): Boolean;

Возвращает True, если имя FileName соответствует групповому имени Mask

Procedure MkDir(Dir: String);

Создает новый каталог на указанном диске: Dir маршрут поиска каталога. Последним именем в маршруте, т.е. именем вновь создаваемого каталога, не может быть имя уже существующего каталога

procedure ProcessPath(const EditText: String; var Drive: Char; var DirPart: String; var FilePart: String);

Возвращает имя диска, маршрут поиска и имя файла в переменных Drive, DirPart и FilePart соответственно. EditText - полное имя файла;

Procedure Rename(var F; NewName: String);

Переименовывает файл F; NewName строковое выражение, содержащее новое имя файла. Перед выполнением процедуры необходимо закрыть файл только для не типизированных файлов и указывает раз мер блока данных

Procedure Reset(var F: File [; RecSize: Word});

Открывает существующий файл. RecSize имеет смысл только для не типизированных файлов и указывает размер блока данных

Procedure Rewrite(varFile [; Recsize: ,Word]) ;

Создает новый файл. Recsize имеет смысл только для не типизированных файлов и указывает размер блока данных

Procedure RmDir(Dir:String);

Удаляет каталог Dir. Удаляемый каталог должен быть пустым, т. е. не содержать файлов или имен каталогов нижнего уровня

С каждой файловой переменой в момент открытия файла связывается структура данных, которая в числе прочих содержит поле Handle - системный дескриптор файла. Это поле следует использовать При обращении К функциям FileGetTime и FileSetTime. Эти функции, а также функция FileAge и поле Time записи TsearchRec (см. ниже) оперируют системным форматом времени-даты, который можно перевести в стандартный тип дата-время с помощью функции FileDateToDateTime (функция DateTimeToFileDate Осуществляет обратное преобразование).

Подпрограммы FindFirst, FindNext и FindClose позволяют получить доступ к группе файлов, объединенных общими признаками. Эти признаки при обращении к функции FindFirst указываются маской выбора файлов и их атрибутами.

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

* означает, что на месте этого символа может стоять сколько угодно (в том числе ноль) разрешенных символов имени или расширения файла;

? означает, что на месте этого символа может стоять один из разрешенных символов.

Например:

* . * выбирает все файлы из каталога;

с* . * выбирает все файлы с именами, начинающимися на с

fcl.pas, ccl2345, с.dat И Т.Д.);

а? . dat выбирает имена файлов типа ао. dat, az. dat и т. д.

Маске выбора может предшествовать маршрут поиска файлов. Например, команда

C:\Dir\SubDir\*.pas

означает выбирать все файлы с расширением .раз из каталога Sub-Dir, находящегося на диске с; каталог subDir зарегистрирован в каталоге верхнего уровня Dir, который, в свою очередь, входит в корневой каталог. Если маршрут не указан, файлы ищутся в текущем каталоге.

Параметр Attr при обращении к FindFirst содержит двоичные разряды (биты), уточняющие, к каким именно файлам разрешен доступ. Вот как объявляются файловые атрибуты в модуле SysUtils:

const

faReadOnly = $01; // Только чтение

faHidden = $02; // Скрытый файл

faSysFile = $04; // Системный файл

faVolumeID = $08; // Идентификатор тома

faDirectory = $10; // Имя подкаталога

faArchive = $20; // Архивный файл

faAnyFile = $3F; // Любой файл

Комбинацией бит в этом байте можно указывать самые разные варианты, например $06 - выбирать все скрытые и/или системные файлы.

Примеры программ.

Задача. Организовать файл целых чисел из 10 компонент. Определить и вывести на экран среднее арифметическое компонент файла. Вывести содержимое файла на экран.

Интерфейс.

Программный код

Type ff=file of Integer; //Декларация физического файла

Var  log_f: ff; //Декларация логического файла

 

Procedure TForm1.FormCreate(Sender: TObject);

Begin

Form1.StringGrid2.Visible:=False;

End;

 

Procedure zapolnenie (Var f:ff); //Заполнение файла

Var i:Integer;    //Параметр цикла

    komp:Integer; //Компонента файла

Begin

Rewrite(f); //Открытие файла для записи

For i:=0 to 9 do

 Begin

 komp:=StrToInt(Form1.StringGrid1.Cells[i,0]); //ввод компонент

 Write (f, komp); //запись в файл

 End;

CloseFile(f);

End;

 

Procedure vyvod(Var f:ff); //вывод файла

Var komp:Integer;

    i:Integer;

Begin

i:=0;

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

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

 Begin

 Read(f,komp); //чтение следующей компоненты файла

 Form1.StringGrid2.Cells[i,0]:=IntToStr(komp); //и вывод ее на экран

 i:=i+1;

 End;

Form1.StringGrid2.Visible:=True;

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

End;

 

Function sr_ar(Var f:ff):Real; //определение среднего арифметического

Var komp:Integer; //компонента файла

    sum:Real;  //сумма компонент

Begin

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

sum:=0;

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

 Begin

 Read(f,komp); //чтение следующей компоненты файла

 sum:=sum+komp; //увеличение счетчика суммы

 End;

sr_ar:=sum/FileSize(f); //получение результата

CloseFile(f);

End;

 

Procedure TForm1.BitBtn1Click(Sender: TObject);

Begin

AssignFile(log_f,'data.dat'); //файл log_f в папке программы имеет имя data.dat

zapolnenie(log_f); //ввести первую строку в StringGridе

vyvod(log_f);

Label1.Caption:='Среднее арифметическое компонент файла= '+FloatToStr(sr_ar(log_f));

End;

Контрольные вопросы.

1.  Что называют физическим файлом?

2.  Что называют логическим файлом?

3.  Как связывается логический файл с физическим файлом?

4.  Для чего и как открываются файлы?

5.  Как закрыть файл?

6.  Что называют текущим указателем?

7.  Опишите операции ввода-вывода для файлов.

 

На главную

Используются технологии uCoz