/* Выполняются все операции чтения. Ожидать завершения события и сразу же сбросить его. События чтения и записи хранятся в массиве событий рядом друг с другом. */
iWaits =0; /* Количество выполненных к данному моменту операций ввода/вывода. */
while (iWaits < 2 * nRecord) {
ic = WaitForMultipleObjects(2 * MAX_OVRLP, hEvents[0], FALSE, INFINITE) – WAIT_OBJECT_0;
iWaits++; /* Инкрементировать счетчик выполненных операций ввода вывода.*/
ResetEvent(hEvents[ic / MAX_OVRLP][ic % MAX_OVRLP]);
if (ic < MAX_OVRLP) {
/* Чтение завершено. */
GetOverlappedResult(hInputFile, &OverLapIn[ic], &nin[ic], FALSE);
/* Обработать запись и инициировать операцию записи. */
CurPosIn.LowPart = OverLapIn[ic].Offset;
CurPosIn.HighPart = OverLapIn[ic].OffsetHigh;
CurPosOut.QuadPart = (CurPosIn.QuadPart / REC_SIZE) * UREC_SIZE;
OverLapOut[ic].Offset = CurPosOut.LowPart;
OverLapOut[ic].OffsetHigh = CurPosOut.HighPart;
/* Преобразовать запись из ASCII в Unicode. */
for (i =0; i < REC_SIZE; i++) UnRec[ic][i] = AsRec[ic][i];
WriteFile(hOutputFile, UnRec[ic], nin[ic] * 2, &nout[ic], &OverLapOut[ic]);
/* Подготовиться к очередному чтению, которое будет инициировано после того, как завершится начатая выше операция записи. */
CurPosIn.QuadPart += REC_SIZE * (LONGLONG)(MAX_OVRLP);
OverLapIn[ic].Offset = CurPosIn.LowPart;
OverLapIn[ic].OffsetHigh = CurPosIn.HighPart;
} else if (ic < 2 * MAX_OVRLP) { /* Операция записи завершилась. */
/* Начать чтение. */
ic –= MAX_OVRLP; /* Установить индекс выходного буфера. */
if (!GetOverlappedResult (hOutputFile, &OverLapOut[ic], &nout[ic], FALSE)) ReportError(_T("Ошибка чтения."), 0, TRUE);
CurPosIn.LowPart = OverLapIn[ic].Offset;
CurPosIn.HighPart = OverLapIn[ic].OffsetHigh;
if (CurPosIn.QuadPart < FileSize.QuadPart) {
/* Начать новую операцию чтения. */
ReadFile(hInputFile, AsRec[ic], REC_SIZE, &nin[ic], &OverLapIn[ic]);
}
}
}
/* Закрыть все события. */
for (ic = 0; ic < MAX_OVRLP; ic++) {
CloseHandle(hEvents[0][ic]);
CloseHandle(hEvents[1][ic]);
}
CloseHandle(hInputFile);
CloseHandle(hOutputFile);
return 0;
}
Программа 14.1 способна работать только под управлением Windows NT. Средства асинхронного ввода/вывода Windows 9x не позволяют использовать дисковые файлы. В приложении В приведены результаты и комментарии, свидетельствующие о сравнительно низкой производительности программы atouOV. Как показали эксперименты, для достижения приемлемой производительности размер буфера должен составлять, по крайней мере, 32 Кбайт, но даже и в этом случае обычный синхронный ввод/вывод работает быстрее. К тому же, производительность этой программы не повышается и в условиях SMP, поскольку в данном примере, в котором обрабатываются всего лишь два файла, ЦП не является критическим ресурсом.
Расширенный ввод/вывод с использованием процедуры завершения