Использование функций Windows API при работе с файлами — КиберПедия 

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...

Использование функций Windows API при работе с файлами

2017-06-02 403
Использование функций Windows API при работе с файлами 0.00 из 5.00 0 оценок
Заказать работу

 

Иногда требуются стандартные функции работы с файлами Windows. Тем более, что возможности в них расширены. Каждый файл в Windows описывается не переменной, а дескриптором (Thandle, можно описывать Cardinal), который представляет собой 32-разрядную величину, идентифицирующую файл в операционной системе. Открывается файл при помощи следующей функции:

function CreateFileA(lpFileName: PAnsiChar;

dwDesiredAccess, dwShareMode: DWORD;

lpSecurityAttributes: PSecurityAttributes;

dwCreationDisposition, dwFlagsAndAttributes: DWORD;

hTemplateFile: THandle): THandle; stdcall;

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

Здесь lpFileName - имя открываемого объекта; dwDesiredAccess – способ доступа к объекту (может иметь значение GENERIC_READ – для чтения, GENERIC_WRITE – для записи или комбинация этих значений). Если dwDesiredAccess =0, то можно получить атрибуты файла без фактического его открытия. Параметр dwShareMode открывает режим совместного с другими программами доступа (0 – совместный доступ запрещен; FILE_SHARE_READ – для чтения; FILE_SHARE_WRITE – для записи; комбинация этих значений – полный доступ). В рассматриваемой функции можно задавать атрибуты защиты объекта - lpSecurityAttributes (если равно nil, то устанавливаются атрибуты по умолчанию). Следующий параметр dwCreationDisposition отвечает за способ открытия объекта (CREATE_NEW – создается новый объект, если таковой существует, - иначе возвращается ошибка ERROR_ALREADY_EXISTS; CREATE_ALWAYS – создается новый объект, если таковой существует, или, если возможно, перезаписывается, - иначе выдается ошибка; OPEN_EXISTING – открывает существующий объект или, если таковой не найден, возвращается ошибка; OPEN_ALWAYS – открывает существующий объект, если таковой не найден, он создается). Набор атрибутов (скрытый, системный, сжатый) и флагов для открытия объекта задается параметром dwFlagsAndAttributes. Последний параметр hTemplateFile задает файл-шаблон, атрибуты которого используются для открытия объекта.

Функция возвращает дескриптор открытого объекта (некоторое число). Если окрыть объект невозможно, то возвращается код ошибки INVALID_HANDLE_VALUE. Более полные сведения об ошибке можно получить, вызвав функцию GetLastError.

Закрывается объект функцией function CloseHandle(hObject: THandle): BOOL; stdcall;.

Для чтения и записи данных используются следующие функции:

function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

function WriteFile(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

Здесь nNumberOfBytesToRead и nNumberOfBytesToWrite – количество байт, которое нужно прочитать или записать; lpNumberOfBytesRead и lpNumberOfBytesWritten - количество байт, которое фактически прочитано или записано. Параметр lpOverlapped – указатель на некоторый дескриптор структуры (типа TOverlapped) события отложенного ввода или вывода, например, для каких-то относительно “медленных” устройств. Создается событие следующей функцией:

function CreateEventA(lpEventAttributes: PSecurityAttributes; bManualReset, bInitialState: BOOL; lpName: PAnsiChar): THandle; stdcall;

Эта функция как раз и возвращает указанный выше дескриптор, на который ссылается параметр lpOverlapped. С помощью данного события автоматически включается отложенный ввод или вывод. Время в миллисекундах (параметр dwMilliseconds), которое разрешается ожидать при отложенном вводе или выводе указывается в функции function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall;, которая прерывает отложенную операцию чтения или записи. Можно задать бесконечный интервал INFINITE.

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

procedure TForm1.Button1Click (Sender: TObject);

var CommPort: string;

hDev: THandle;

ModemStat: DWord;

begin

CommPort:= 'COM1';

hDev:= CreateFile(PChar(CommPort),

GENERIC_READ,0,nil, OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL, 0);

if hDev = INVALID_HANDLE_VALUE then begin

ShowMessage('Ошибка открытия порта '+ CommPort);

exit;

end;

if GetCommModemStatus(hDev,ModemStat) <>false

then begin

if ModemStat and MS_CTS_ON <> 0 then

ShowMessage(

'Управление CTS (clear-to-send) в порядке.');

if ModemStat and MS_DSR_ON <>0 then

ShowMessage(

'Управление DSR (data-set-ready) в порядке.');

if ModemStat and MS_RING_ON <> 0then

ShowMessage(

'Управление ring indicator в порядке.');

if ModemStat and MS_RLSD_ON <> 0 then

ShowMessage('Управление RLSD

(receive-line-signal-detect) в порядке.');

end;

CloseHandle(hDev);

end;

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

Const SectorSize=512;

Var Buffer:Pointer;

FUNCTION TForm1.ReadSector(Head,Track,Sector:integer;

Buffer:pointer):boolean;

var

hDev:THandle;

DevName:string;

nb:cardinal;

begin

DevName:='\\.\A:';

hDev:=CreateFile(pChar(DevName),GENERIC_READ,

FILE_SHARE_READ or FILE_SHARE_WRITE,nil,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);

if hDev=INVALID_HANDLE_VALUE then begin

Result:=false;

Exit;

end;

SetFilePointer(hDev,(Sector-1)*SectorSize,nil,

FILE_BEGIN);

Result:= ReadFile(hDev,Buffer,SectorSize,nb,nil)

and (nb=SectorSize);

CloseHandle(hDev);

end;

В данном примере для позиционирования файлового указателя применяется еще одна функция Windows API SetFilePointer, объявленная следующим образом:

function SetFilePointer(hFile: THandle;

lDistanceToMove: Longint; lpDistanceToMoveHigh:

Pointer; dwMoveMethod: DWORD): DWORD; stdcall;.

Как следует из примера функции ReadSector, позиционирование файлового указателя не учитывает значений параметров Head и Track (опущено для упрощения). При необходимости можно добавить взаимосвязь всех трех параметров.

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

 

ПРИМЕР 25

 

Пусть имеется текстовый файл, созданный по правилам Delphi. Требуется открыть этот файл указанной выше функцией Windows API и прочитать его содержимое. При выполнении этого примера встретятся некоторые трудности из-за того, что придется читать файл как совокупность байтов, а потом эти байты пытаться интерпретировать. Вариант решения примера приводится на рис. 61.

Рис. 61 Вариант решения примера 25.

Ниже приводится текст программы.

unit UMSfile;

Interface

uses Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms, Dialogs, StdCtrls,

Buttons;

Type

TForm1 = class(TForm)

Button1: TButton;

Memo1: TMemo;

BitBtn1: TBitBtn;

Memo2: TMemo;

Label1: TLabel;

procedure Button1Click (Sender: TObject);

procedure FormDeactivate (Sender: TObject);

public

hDev:THandle;

end;

var Form1: TForm1;

Buffer:pointer;

FilSize:cardinal;

Implementation

{$R *.dfm}

procedure TForm1.Button1Click (Sender: TObject);

type buf=array of byte;

var FilName:string;

nb:cardinal;

i,r:byte;

F:File;

sNumber:string[3];

begin

FilName:='InpFil.txt';

Buffer:= Nil;

FilSize:=0;

{$I-}

AssignFile(F, FilName);

System.Reset(F, 1);

{$I+}

if IOResult<>0 then begin

memo1.Lines.Add('Ошибка открытия файла');

Exit;

End;

FilSize:= FileSize(F);

closeFILE(F);

memo1.Lines.Add('FilSize= '+inttostr(FilSize));

memo2.Lines.LoadFromFile(FilName);

hDev:=CreateFileA(pChar(FilName),GENERIC_READ,

FILE_SHARE_READ or FILE_SHARE_WRITE,nil,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);

if hDev=INVALID_HANDLE_VALUE then begin

memo1.Lines.Add(' Ошибка открытия файла Windows');

Exit;

end;

try

Getmem(Buffer,FilSize);

ReadFile(hDev,Buffer,FilSize,nb,nil);

memo1.Lines.Add('Прочитано байтов’+inttostr(nb));

memo1.Lines.Add('Прочитаны числа');

sNumber:='';

FOR I:=0 TO FilSize DO BEGIN

r:=buf(@buffer)[I];

if chr(r) in ['0'..'9'] then

sNumber:=sNumber+chr(r)

else begin

if length(sNumber)>0 then

memo1.Lines.Add(sNumber);

sNumber:='';

end;

END;

finally

CloseHandle(hDev);

end;

end;

procedure TForm1.FormDeactivate (Sender: TObject);

begin

FreeMem(Buffer,FilSize);

end;

end.

В данной программе вначале определяется количество байт в исходном файле, которое включает в себя все символы, содержащиеся в файле, в том числе и разделители, т.е. отдельные цифры чисел, пробелы, #13, #10. Далее этот файл открывается как файл Windows. Байты считываются в переменную Buffer и с помощью преобразования типа Pointer в тип Array of byte восстанавливаются в исходные числа. В примере показан один из вариантов работы с типом Pointer.

 


Поделиться с друзьями:

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...

Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.03 с.