Асинхронный файловый ввод/вывод в операционной системе WINDOWS, страница 14

cerr<<"Соединение готово (^C для отсоединения)\n";

if (err!=ERROR_IO_PENDING)

{

cerr<<"Ошибка чтения канала ("<<err<<")\n";

exit(3);

}

// Вход в ожидание

while (1)

{

if (WaitForSingleObject(console,0)==WAIT_OBJECT_0)

{

char inbuf; // ANSI только

INPUT_RECORD irec;

dummy.hEvent=NULL;

dummy.Offset=dummy.OffsetHigh=dummy.Internal=dummy.InternalHigh=0;

DWORD inlen;

// используя ReadConsole консоль остается в сигнальном состоянии

ReadConsoleInput(console,&irec,1,&inlen);

if (irec.EventType==KEY_EVENT&&irec.Event.KeyEvent.bKeyDown&&

irec.Event.KeyEvent.uChar.AsciiChar!='\0')

{

inbuf=irec.Event.KeyEvent.uChar.AsciiChar;

if (inbuf=='\003')

{

// завершение

CloseHandle(pipe);

exit(0);

}

WriteFile(pipe,&inbuf,1,&inlen,&dummy);

// Эхо

cout<<((inbuf=='\r')?'\n':inbuf);

cout.flush();

}

}

// если ожидание канала завершено, вывести символ на консоль

DWORD rsiz,key;

OVERLAPPED *o;

if (GetQueuedCompletionStatus(port,&rsiz,&key,&o,0))

{

if (o==&dummy) continue; // была запись

do

{

if (pipebuf=='\r') cout<<'\n'; else cout<<pipebuf;

} while (ReadFile(pipe,&pipebuf,1,&inlen,&over));

DWORD err=GetLastError();

if (err!=ERROR_IO_PENDING)

{

cerr<<"Ошибка чтения канала\n";

exit(3);

}

cout.flush();

}

// Предполагается, что здесь выполняется какая-то полезная работа....

}

}

Еще один способ доступа к файлам

Одной экзотической технологией, являются файлы, отображенные на память. Менеджер виртуальной памяти Windows позволяет программе работать с файлом таким образом, будто этот файл полностью загружен в оперативную память компьютера. На самом деле это не так. Менеджер виртуальной памяти загружает в оперативную память компьютера только фрагменты файла. Эти фрагменты называют страницами. Для компьютеров, оснащенных процессором Pentium, каждая страница обычно имеет размер 4 Кбайт. Вместе с тем при использовании других процессоров размер страницы может быть другим. Когда программа обращается к данным, расположенным в определенной позиции файла, менеджер виртуальной памяти загружает в память соответствующую страницу. Как только страница перестает быть нужной, на ее место в оперативной памяти могут быть записаны другие данные.

Чтобы отобразить файл на оперативную память, откройте его при помощи  вызова CreateFile и передайте дескриптор файла вызову CreateFileMapping. При этом будет создан объект отображения файла. Такие же объекты используютсявWindows для организации памяти общего доступа (вспомните лаб.работу УПРАВЛЕНИЕ ПАМЯТЬЮ в ОС Windows). Если объект будет доступен для нескольких процессов, ему необходимо присвоить имя. Однако, если объект создается только лишь для того, чтобы работать с файлом в режиме отображения его на память, имя можно не присваивать. Чтобы получить доступ к файлу, отображенному на память, обратитесь к функции MapViewOfFi1e. Эта функция вернет указатель на содержимое файла.

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

При отображении файла на оперативную память необходимо сообщить количество байт (файла), с которым вы собираетесь работать. Это значение передается в качестве одного из аргументов вызова CreateFileMapping. Если это значение равно 0 (ноль), на память будет отображен весь файл. При желании можно передать значение либо большее, либо меньшее, чем длина файла. После того как вы установили это значение, изменить его нельзя. Таким образом, если при добавлении данных в конец файла указанный размер оказался недостаточным, вы не сможете продолжить запись. В этом случае придется закрыть отображенный на память файл и открыть его заново, указав при этом больший размер.