Цель работы
Изучение способов работы с файлами в Win32 API. Изучение асинхронного режима работы с файлами.
Список используемых системных вызовов
CreateFile,
CloseHandle, ReadFile, WriteFile, CancelIo, WaitForSingleObject,
WaitForMultipleObjects, GetFilePointer, SetFilePointer, FindFirstFile,
FindNextFile, FindClose, SearchFile.
Методические указания
При выполнении данной лабораторной работы запрещается
пользоваться группами функций Win32 API CopyFile… и MoveFile…, а также функциями библиотеки shell32.dll.
Для создания/открытия файла в Win32 API используется функция CreateFile (параметр dwCreationDisposition
используется для задания режима открытия или создания файла). Чтение из файла и
запись в файл реализуются с помощью функций ReadFile
и WriteFile. Дескриптор файла закрывается с
помощью стандартной функции CloseHandle.
Поиск файла в заданном каталоге возможен с помощью функций FindFirstFile, FindNextFile, FindClose. Поиск файла по путям поиска
производится с помощью функции SearchFile.
В Win32 API реализована
возможность задания асинхронного режима работы с файлами. Этот режим работает
только в Windows NT-based операционных системах.
При использовании этого режима чтение и запись в файл реализуются параллельно
работе нити, задавшей файловую операцию. Для обеспечения возможности
асинхронного режима работы с файлом необходимо в параметре dwFlagsAndAttributes функции CreateFile задать битовый флаг FILE_FLAG_OVERLAPPED.
После этого параметр lpOverlapped
у функций чтения и записи в файл должен являться указателем на экземпляр
структуры OVERLAPPED, представленной
ниже:
typedef struct
_OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED;
Параметры структуры Offset и OffsetHigh задают
начальное смещение от начала файла для выполнения файловой операции. Дескриптор
hEvent должен быть верным дескриптором события,
порожденного с помощью функции CreateEvent.
Параметры Internal и InternalHigh используются самой ОС.
После задания асинхронной операции с файлом функция ReadFile или WriteFile
немедленно возвращает управление. После окончания файловой операции событие hEvent переходит в сигнальное состояние и может
быть проверено с помощью стандартных WaitFor-функций.
Функция CancelIo
немедленно прекращает все ждущие асинхронные файловые операции по заданному
дескриптору файла для текущей нити.
Задания
11. Разработать программу,
осуществляющую подсчет числа слов в текстовом файле. Чтение файла должно
осуществляться параллельно подсчету. Процесс программы должен состоять из одной
нити.
Листинг
программы.
#include
<stdio.h>
#include
<windows.h>
void main()
{
HANDLE hFile;
OVERLAPPED over;
DWORD dByte,dwError;
int iByteToRead=1;
BOOL bResult;
int
iWord=0,tek=0,pred=0,iBreak=0,iBegin=1,iEnd=1; //новое
слово - tek=1,pted=0;
over.Offset=0;
over.OffsetHigh=0;
char cBuffer[1];
// Создаём событие для
контроля за асинхронным чтением
over.hEvent = CreateEvent(NULL,
TRUE, FALSE, NULL);
if(over.hEvent==NULL)
{
printf("\nError
create event!!!");
exit(0);
// Ошибка создания
события …
}
hFile=CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
printf("\nError
opening file!!!");
exit(0);
}
while(1)
{
bResult =
ReadFile(hFile,cBuffer,iByteToRead,&dByte,&over);
// если возникает
проблема или асинхронная операция
//
все еще ожидает обработки ...
if (!bResult)
{
//
решаем что делать с кодом ошибки
switch (dwError = GetLastError())
{
case
ERROR_HANDLE_EOF:
{
//
мы достигли конца файла
//
в течение вызова к ReadFile
iBreak=1;
break;
}
case
ERROR_IO_PENDING:
{
//
асинхронный ввод-вывод все еще происходит
//
сделаем кое-что пока он идет
// GoDoSomethingElse()
;
over.Offset++;
pred=tek;
if(cBuffer[0]=='
'|| cBuffer[0]=='\x0D' || cBuffer[0]=='\n')tek=0;
else
tek=1;
if(tek==1
&& pred==0)iWord++;
//
проверим результат работы асинхронного чтения
bResult
= GetOverlappedResult(hFile, &over, &dByte,
FALSE) ;
//
если возникла проблема ...
if (!bResult)
{
//
решаем что делать с кодом ошибки
switch (dwError = GetLastError())
{
case
ERROR_HANDLE_EOF:
{
//
мы достигли конца файла
//
в ходе асинхронной
// операции
iBreak=1;
break;
}
default:
{
printf("\nError
work to file!!!");
iBreak=1;
break;// решаем что делать с
другими случаями ошибок
}
}//
конец процедуры switch (dwError = GetLastError())
}
break;
}
// конец процедуры case
default:
{
printf("\nError
work to file!!!");
iBreak=1;
break; // решаем что делать с другими случаями ошибок
}
} // конец
процедуры switch (dwError = GetLastError())
} // конец процедуры if
if(iBreak==1)break;
over.Offset++;
pred=tek;
if(cBuffer[0]==' ' ||
cBuffer[0]=='\x0D' || cBuffer[0]=='\n')tek=0;
else tek=1;
if(tek==1 &&
pred==0)iWord++;
}
printf("\nIn text %d
words!!!", iWord);
getchar();
}
Вывод: изучили способы работы с файлами в Win32 API, изучили асинхронный режим
работы с файлами.
Комментариев нет:
Отправить комментарий