Операционные системы. Учебное пособие. Марапулец Ю.В. - 183 стр.

UptoLike

Составители: 

Если канал находится в режиме чтения сообщений, функция PeekNamedPipe() все-
гда останавливается, прочитав первое сообщение, - даже если в буфере осталось место
для нескольких сообщений. Кроме того, функция PeekNamedPipe() никогда не блокиру-
ет пустой канал, как это делает функция ReadFile() при установленном флаге
PIPE_WAIT. Режим ожидания не влияет на функцию PeekNamedPipe(), которая всегда
возвращает результат немедленно.
Все операции, которые выполнялись при создании канала - именованного или ано-
нимного, блокируемого или неблокируемого, байтового канала или канала сообщений, -
являлись подготовительными, обеспечивающими возможность передачи данных по это-
му каналу. Для операций непосредственно чтения - записи используются функции Wri-
teFile() и ReadFile(). Данные функции, как и CreateFile() рассмотрены нами ранее при
изучении файлового ввода-вывода. Однако рассмотрим их еще раз с учетом специфики
каналов.
BOOL WriteFile(
HANDLE hFile, // куда записывать (канал или файл)
CONST VOID *lpBuffer, //указывает данные, которые должны быть
// записаны в файл
DWORD dwBytesToWrite, // количество записываемых байтов
LPDWORD lpdwBytesWritten, // возвращает количество записанных байтов
LPOVERLAPPED lpOverlapped ); // задает поддержку асинхронного
// ввода/вывода
BOOL ReadFile(
HANDLE hFile; // источник для чтения данных (канал или файл)
LPVOID lpBuffer; // буфер для временного хранения
// прочитанных данных
DWORD dwBytesToRead; // количество байтов, которые должны быть
// прочитаны
LPDWORD lpdwBytesRead; // возвращает количество прочитанных байтов
LPOVERLAPPED lpOverlapped ); // поддержка асинхронного ввода/вывода
Количество байтов, которые должны быть прочитаны или записаны, не обяза-
тельно должно совпадать с размером буфера, однако превышать этот размер оно не мо-
жет. Если при вызове функции ReadFile() для канала, который работает в режиме сооб-
щений, вы зададите параметру dwBytesToRead значение, меньшее, чем размер
следующего сообщения, функция ReadFile() прочитает только часть сообщения и воз-
вратит значение FALSE.
Если после этого проанализировать причину ошибки, вызвав
функцию GetLastError(), она возвратит код ошибки ERROR_MORE_DATA.
Чтобы про-
читать остаток сообщения, следует снова вызвать функцию ReadFile() или PeekNamed-
Pipe(). Если функция WriteFile() записывает данные в неблокируемый канал, который
работает в байтовом режиме, и видит, что его буфер почти заполнен, она все равно воз-
вращает значение TRUE, однако значение lpdwBytesWritten окажется меньшим, чем зна-
чение dwBytesToWrite.
В зависимости от режима ожидания канала функции WriteFile() и ReadFile() могут
блокироваться. Функция WriteFile() может ожидать, пока заполненный канал не осво-
бодится на другом конце. Функция ReadFile() может быть заблокирована пустым кана-
лом вплоть до момента поступления нового сообщения.
Последний параметр обеих функции представляет собой указатель на структуру
OVERLAPPED,
которая содержит дополнительную информацию, предназначенную для
поддержки асинхронного или перекрывающегося ввода/вывода, который рассмотрен
нами ранее.
185
      Если канал находится в режиме чтения сообщений, функция PeekNamedPipe() все-
гда останавливается, прочитав первое сообщение, - даже если в буфере осталось место
для нескольких сообщений. Кроме того, функция PeekNamedPipe() никогда не блокиру-
ет пустой канал, как это делает функция ReadFile() при установленном флаге
PIPE_WAIT. Режим ожидания не влияет на функцию PeekNamedPipe(), которая всегда
возвращает результат немедленно.
      Все операции, которые выполнялись при создании канала - именованного или ано-
нимного, блокируемого или неблокируемого, байтового канала или канала сообщений, -
являлись подготовительными, обеспечивающими возможность передачи данных по это-
му каналу. Для операций непосредственно чтения - записи используются функции Wri-
teFile() и ReadFile(). Данные функции, как и CreateFile() рассмотрены нами ранее при
изучении файлового ввода-вывода. Однако рассмотрим их еще раз с учетом специфики
каналов.

BOOL WriteFile(
     HANDLE hFile,                // куда записывать (канал или файл)
     CONST VOID *lpBuffer,        //указывает данные, которые должны быть
                                  // записаны в файл
     DWORD dwBytesToWrite,        // количество записываемых байтов
     LPDWORD lpdwBytesWritten,    // возвращает количество записанных байтов
     LPOVERLAPPED lpOverlapped ); // задает поддержку асинхронного
                                  // ввода/вывода
BOOL ReadFile(
     HANDLE hFile;         // источник для чтения данных (канал или файл)
     LPVOID lpBuffer;             // буфер для временного хранения
                                  // прочитанных данных
     DWORD dwBytesToRead;         // количество байтов, которые должны быть
                                  // прочитаны
     LPDWORD lpdwBytesRead;       // возвращает количество прочитанных байтов
     LPOVERLAPPED lpOverlapped ); // поддержка асинхронного ввода/вывода

      Количество байтов, которые должны быть прочитаны или записаны, не обяза-
тельно должно совпадать с размером буфера, однако превышать этот размер оно не мо-
жет. Если при вызове функции ReadFile() для канала, который работает в режиме сооб-
щений, вы зададите параметру dwBytesToRead значение, меньшее, чем размер
следующего сообщения, функция ReadFile() прочитает только часть сообщения и воз-
вратит значение FALSE. Если после этого проанализировать причину ошибки, вызвав
функцию GetLastError(), она возвратит код ошибки ERROR_MORE_DATA. Чтобы про-
читать остаток сообщения, следует снова вызвать функцию ReadFile() или PeekNamed-
Pipe(). Если функция WriteFile() записывает данные в неблокируемый канал, который
работает в байтовом режиме, и видит, что его буфер почти заполнен, она все равно воз-
вращает значение TRUE, однако значение lpdwBytesWritten окажется меньшим, чем зна-
чение dwBytesToWrite.
      В зависимости от режима ожидания канала функции WriteFile() и ReadFile() могут
блокироваться. Функция WriteFile() может ожидать, пока заполненный канал не осво-
бодится на другом конце. Функция ReadFile() может быть заблокирована пустым кана-
лом вплоть до момента поступления нового сообщения.
      Последний параметр обеих функции представляет собой указатель на структуру
OVERLAPPED, которая содержит дополнительную информацию, предназначенную для
поддержки асинхронного или перекрывающегося ввода/вывода, который рассмотрен
нами ранее.


                                        185