Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Низкоуровневые методы работы с файлами



Операционная система Windows осуществляет работу с файлами при помощи дескрипторов – указателей на файл как на физическое устройство. В составе Delphi предусмотрен специальный набор функций для работы с файлами в стиле Windows (табл. 4.2).

 

 

Таблица 4.2. Функции, работающие с файлами в стиле Windows

Метод Описание
function FileCreate(const FileName: string): Integer;     function FileOpen(const FileName: string; Mode: LongWord): Integer;     function FileSeek(Handle, Offset, Origin: Integer): Integer;     function FileRead(Handle: Integer; var Buffer; Count: Integer): Integer;     function FileWrite(Handle: Integer; const Buffer; Count: Integer): Integer;     function FileGetDate(Handle: Integer): Integer;   function FileSetDate(Handle: Integer; Age: Integer): Integer;     procedure FileClose(Handle: Integer); Создает файл с именем FileName и возвращает указатель на него. Если в процессе создания произошла ошибка, то функция вернет –1. Для закрытия файла обязателен вызов метода FileClose().   Открывает файл FileName и возвращает указатель на него. Для закрытия файла обязателен вызов метода FileClose(). Файл открывается в режиме, определенном в параметре Mode (см. табл. 4.3).   Позиционирует файл с дескриптором Handle в положение Offset. Порядок смещения определяется параметром Origin: 0 – Offset байт от начала файла; 1 – Offset байт от текущей позиции; 2 – Offset байт от конца файла.   Читает Count байт в буфер Buffer из файла с дескриптором Handle. Используется совместно с FileOpen() или FileCreate().   Записывает Count байт из буфера Buffer в файл с дескриптором Handle. Дескриптор получают от функций FileOpen() или FileCreate().   Возвращает дату/время создания файла в формате операционной системы.   Устанавливает время создания файла Age с дескриптором Handle. Время должно передаваться в формате операционной системы.   Закрывает файл с дескриптором Handle. Используется совместно с функциями FileOpen() или FileCreate().

 

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

 

Таблица 4.3. Режимы открытия файла

Режим Значение Описание
fmOpenRead fmOpenWrite fmOpenReadWrite fmShareCompat   fmShareExclusive   fmShareDenyWrite fmShareDenyRead fmShareDenyNone $0000; $0001; $0002; $0000;   $0010;   $0020; $0030; $0040; Открыть только для чтения Открыть только для записи Открыть для чтения и записи Совместимость со старой моделью доступа к файлам Запретить другим читать файл и записывать в него Запретить другим запись в файл Запретить другим чтение файла Разрешить другим полный доступ

Асинхронные операции ввода-вывода

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

Для организации асинхронных операций ввода-вывода целесообразно использовать методы Win32 API ReadFileEx() и WriteFileEx().

 

Function ReadFileEx (hFile : THandle; Buf : pointer; NumberOfBytesToRead

: cardinal; const Overlapped : pOverlapped; CompletionRoutine : pointer)

: Boolean;

 

Function WriteFileEx (hFile : THandle; Buf : pointer; NumberOfBytesTo-

Write : cardinal; const Overlapped : pOverlapped; CompletionRoutine :

pointer) : Boolean;

 

Здесь hFile – дескриптор файла, полученный при помощи методов Win32 API OpenFile() и CreateFile() или соответствующих методов Object Pascal FileOpen() и CreateFile(). Buf – указатель на буфер, в который будут помещаться прочитанные данные или, наоборот, данные из которого будут записываться в файл. Третий параметр возвращает общее количество прочитанных (NumberOfBytesToRead) или записанных (NumberOfBytesToWrite) байт. Особый интерес вызывает четвертый аргумент – указатель на специальную структуру OVERLAPPED, содержащую данные, которые будут использоваться при асинхронном чтении (или записи).

 

Type

POverlapped = ^TOverlapped;

_OVERLAPPED = record

Internal: DWORD;

InternalHigh: DWORD;

Offset: DWORD;

OffsetHigh: DWORD;

hEvent: THandle;

end;

Поля Internal и InternalHigh зарезервированы за операционной системой. В частности, они используются ОС для определения статуса проводимой асинхронной операции. Поля Offset и OffsetHigh соответственно хранят 32 младших и 32 старших бита позиции файла, с которой должно начинаться чтение или запись. Поле hEvent содержит дескриптор специального объекта синхронизации, называемого событием. Его мы изучим в главе 20 «Процессы и потоки в среде Windows». В данном контексте объект-событие применяется для передачи информации процедуре завершения. Последний параметр методов ReadFileEx() и WriteFileEx() – указатель на функцию обратного вызова FileIOCompletionRoutine(). Эта функция вызывается при завершении или отмене операции ввода-вывода.

 

Управление файлами, дисками и каталогами

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

 

Проверка наличия файла и каталога

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

 

function FileExists (const FileName: string): Boolean;

function DirectoryExists (const Directory: string): Boolean;

 

Функции возвращают true, если файл (каталог) действительно существует.

 

Удаление, копирование и перемещение файлов

Нет ничего проще, чем просто удалить файл. Для этого достаточно знать имя

стираемого файла и название соответствующего метода:

 

functionDeleteFile (const FileName: string): Boolean;

 

Если по какой-то причине удалить файл невозможно, то функция возвратит false.

В составе стандартных функций Pascal отсутствуют методы, осуществляющие копирование и перемещение файлов. Для решения задач такого рода достаточно воспользоваться функциями из набора Windows API. Для копирования файлов используйте функцию Windows API CopyFile():

 

Function CopyFile (ExistingFileName, NewFileName : PChar; FailIfExists : Boolean): Boolean;

 

Параметры метода: ExistingFileName – указатель на строку с полным именем копируемого файла; NewFileName – указатель на строку с полным именем нового файла; параметр FailIfExists определяет поведение метода при совпадении имен – если параметр равен true и файл с таким именем уже существует, то копирование прерывается. В случае успеха функция CopyFile() возвращает ненулевое значение.

 

var pExName, pNewName : PChar;

Begin

pExName:=PChar('C:\1.txt');

pNewName:=PChar('С:\Copy_Of_1.txt');

CopyFile(pExName,pNewName,true);

end;

 

Для перемещения файлов используйте функцию MoveFile():

 

Function MoveFile(ExistingFileName, NewFileName : PChar) : Boolean;

 

Параметры функции MoveFile() идентичны первым двум аргументам метода CopyFile(). В случае успеха функция возвращает ненулевое значение.

 

Имя файла и путь к нему

Широкий спектр методов нацелен на организацию работы с именем файла, его расширением и путем к файлу. Почти все рассматриваемые методы объявлены в модуле SysUtils.

 

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

Функция Описание
function ChangeFileExt(const FileName, Extension: string): string;     function ExcludeTrailingBackslash( const S: string): string;   function IncludeTrailingBackslash( const S: string): string; function ExpandFileName(const File- Name: string): string; function ExpandUNCFileName(const FileName: string): string; function ExtractFileDir(const FileName: string): string;   function ExtractFilePath(const File- Name: string): string; function ExtractFileDrive(const FileName: string): string; function ExtractFileExt(const FileName: string): string;   function ExtractFileName(const FileName: string): string; function ExtractRelativePath(const BaseName, DestName: string): string;     functionExtractShortPathName(const FileName: string): string; function IsPathDelimiter(const S: string; Index: Integer): Boolean; function MatchesMask(const Filename, Mask: string): Boolean; procedure ProcessPath(const EditText: string; var Drive: Char; var DirPart: string; var FilePart: string); function MinimizeName(const Filename: TFileName; Canvas: TCanvas; MaxLen: Integer): TFileName; Изменяет расширение в имени файла FileName на новое, определенное параметром Extension. Возвращает новое значение имени.   Удаляет последнюю наклонную черту (слэш) в пути S.   Завершает путь S наклонной чертой.   Преобразует имя файла FileName в полный путь к файлу, включая имена файла и диска. Преобразует имя файла в полный путь к сетевомуфайлу:\\<Имя_сервера>\<Ресурс>   Извлекает из строки с полным именем файла путь к каталогу файла и имя каталога.   Извлекает из строки с полным именем файла путь к файлу, заканчивающийся слэшем. Извлекает из строки с полным именем файла имя диска, завершающееся двоеточием. Возвращает расширение в имени файла. В результирующую строку входит разделительная точка и непосредственно расширение. Извлекает из строки с полным именем файла имя и расширение файла. Возвращает относительный путь к файлу. Здесь DestName – полный путь, BaseName – путь, вычитаемый из полного пути. FileName:='C:\Windows\System\comctrl32.dll'; Result:=ExtractRelativePath('c:\windows\',FileName); В результате будет получена строка System\comctrl32.dll Конвертирует полный путь к файлу в укороченный формат 8.3.   Проверяет наличие в позиции Index символа наклонной черты влево. Проверяет соответствие имени файла шаблону маски. Функция определена в модуле Masks. Разделяет полный путь к файлу на составные части: имя диска, путь к каталогу, имя файла. Функция определена в модуле FileCtrl.   Функция определена в модуле FileCtrl. Метод применяется совместно с элементами управления, обладающими канвой Canvas (поверхностью для рисования). Задача метода – поместить имя файла FileName в области, ограниченной по ширине MaxLen пикселами. В соответствии с ограничениями функция минимизирует имя файла.

Дата и время создания файла

Самый простой способ знакомства с возрастом файла заключается в использовании функции:

 

function FileAge(const FileName: string): Integer;

 

Как видите, для этого достаточно передать путь и имя файла в параметр FileName. Еще один метод, выполняющий аналогичную задачу:

 

function FileGetDate (Handle: Integer): Integer;

 

Однако здесь вместо имени требуется указатель на файл. Другими словами, последний должен быть открыт методом FileOpen() или создан методом FileCreate(). Оба метода возвращают дату не в привычном для нас формате TDateTime, а в виде структуры даты-времени, принятой в Windows. Поэтому для приведения результата к понятному для языка Pascal виду применяется метод:

 

function FileDateToDateTime(FileDate: Integer): TDateTime;

 

Существует функция, решающая и обратную задачу:

 

function DateTimeToFileDate(DateTime: TDateTime): Integer;

varFileName : string;

Age : INTEGER;

Begin

FileName:='C:\Autoexec.bat';

Age:=FileAge(FileName);

WriteLn(Age);

WriteLn(DateTimeToStr(FileDateToDateTime(Age)));

ReadLn;

End.

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

 

function FileSetDate(Handle: Integer; Age: Integer): Integer;

var FileName : string;

F,Age : INTEGER;

. . .

Age:=DateTimeToFileDate(Now);

F:=FileOpen(FileName, fmOpenReadWrite);

FileSetDate(F, Age);

FileClose(F);

 

Атрибуты файла

В языке Pascal объявлено два метода для работы с атрибутами файла. За чтение и установку атрибутов отвечают соответственно методы:

 

function FileGetAttr(const FileName: string): Integer;

functionFileSetAttr(const FileName: string; Attr: Integer): Integer;

 

В обеих функциях FileName – имя файла. Во втором методе назначение атрибутов выполняется с помощью параметра Attr. Существующие типы атрибутов представлены в табл. 4.5.

 

Таблица 4.5. Атрибуты файла

Атрибут Значение Описание
faReadOnly faHidden faSysFile faVolumeID faDirectory faArchive faAnyFile $00000001 $00000002 $00000004 $00000008 $00000010 $00000020 $0000003F Только для чтения Скрытый Системный Диск Каталог Архив Любой

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

 

function DeleteMyFile(FileName : string) : Boolean;

var Attr : INTEGER;

Begin

Attr:=FileGetAttr(FileName);

if (Attr and faHidden = 0) or (Attr and faSysFile = 0) then

Begin

DeleteFile(FileName);

Result:=True;

end else Result:=False;

ReadLn;

End.

 

Наиболее частая операция, связанная с установкой (удалением) атрибута «только для чтения», унифицирована и представлена в лице метода:

 

function FileSetReadOnly(const FileName: string; ReadOnly: Boolean): Boolean;

 

Здесь FileName – имя файла, ReadOnly – состояние атрибута.

 

Размер файла

Зачастую применение входящего в арсенал Delphi метода FileSize() недостаточно удобно, т. к. его единицей измерения является не байт, а запись. Для выяснения размера файла в байтах можно использовать метод из состава Windows API:

 

FunctionGetFileSizeEx(hFile : HANDLE; pFileSize : Pointer) : Boolean;

 

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

 

var FileName : string;

F : Integer;

Size : INT64;

Begin

FileName:='C:\autoexec.bat';

F:=FileOpen(FileName,fmOpenRead);

Size:=GetFileSize(F, @Size);

WriteLn(Size);

FileClose(F);

ReadLn;

End.







Читайте также:

Последнее изменение этой страницы: 2016-03-17; Просмотров: 91; Нарушение авторского права страницы


lektsia.com 2007 - 2017 год. Все права принадлежат их авторам! (0.277 с.) Главная | Обратная связь