<Return[R]><Top>

ReadFileEx

Declare Function Api_ReadFileEx& Lib "kernel32" Alias "ReadFileEx" (ByVal hFile&, lpBuffer As Any, ByVal nNumberOfBytesToRead&, lpOverlapped As OVERLAPPED, ByVal lpCompletionRoutine&)

Declare Function ReadFileEx Lib "kernel32" Alias "ReadFileEx" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpOverlapped As OVERLAPPED, ByVal lpCompletionRoutine As Long) As Long

ファイルからデータを非同期的に読み取る。 ReadFile 関数は同期と非同期の両方の操作を想定して設計されているが、ReadFileEx 関数は非同期の操作だけを想定して設計されている。ReadFileEx 関数を使うと、アプリケーションはファイルの読み取り操作を行っている間に、他の処理を実行できる。
読み取り操作が完了または取り消された時点で、呼び出し側スレッドがアラート可能な待機状態になっている場合、ReadFileEx 関数は指定の完了ルーチンを呼び出して、完了のステータスを非同期で報告する。

パラメータ
hFile
    読み取り対象のファイルのハンドルを指定する。このハンドルは、FILE_FLAG_OVERLAPPED フラグを指定して作成したものでなければな

    らない。また、GENERIC_READ アクセス権も備えていなければならない。
    Windows NT/2000:FILE_FLAG_OVERLAPPED フラグを指定し CreateFile 関数を呼び出して開いた任意のハンドル、または と どちら

    かの関数が返したソケットのハンドルを指定する。
    Windows 95/98:FILE_FLAG_OVERLAPPED フラグを指定し CreateFile 関数を呼び出して開いた通信リソース、または socket と

    accept どちらかの関数が返したソケットのハンドルを指定する。メールスロット、名前付きパイプ、ディスクファイルに対する非同期読み取り操

    作はサポートしていない。
lpBuffer
    1 個のバッファへのポインタを指定します。関数から制御が返ると、このバッファに、ファイルから読み取ったデータが格納される。
    このバッファは、読み取り操作が完了するまで、常に有効な状態にしておかなければならない。また、読み取り操作が完了するまで、アプ

    リケーションはこのバッファを使うべきではない。
nNumberOfBytesToRead
    読み取り対象のバイト数を指定する。
lpOverlapped
    1 個の 構造体へのポインタを指定する。この構造体は、非同期(オーバーラップ)ファイル読み取り操作の際に使われるデータを提供す

    る。hFile パラメータで指定したファイルがバイトオフセットの概念をサポートしている場合、呼び出し側は読み取りを開始するバイトオフセットを

    指定しなければならない。OVERLAPPED 構造体の Offset と OffsetHigh の各メンバを設定して、バイトオフセットを指定する。
    ReadFileEx 関数は、 構造体の hEvent メンバを無視する。アプリケーションは、ReadFileEx を呼び出すコンテキストで、このメンバを自由

    に使ってかまわない。ReadFileEx 関数は、lpCompletionRoutine パラメータが指す完了ルーチンを呼び出す(または呼び出しの指示をキ

    ューに入れる)ことによって、読み取り操作の完了を通知するので、イベントのハンドルは必要ない。
    ReadFileEx 関数は、OVERLAPPED 構造体の Internal と InternalHigh の各メンバを使います。アプリケーションは、これらのメンバに

    値を設定するべきではありません。
    lpOverlapped パラメータが指す OVERLAPPED 構造体は、読み取り操作が完了するまで、常に有効な状態にしておかなければならな

    い。非同期読み取り操作の進行中にスコープから外れてしまう変数を指定しないよう注意する。
lpCompletionRoutine
    完了ルーチンへのポインタを指定する。読み取り操作が完了し、かつ、呼び出し側スレッドがアラート可能な待機状態になっている場合、こ

    の完了ルーチンが呼び出される。

戻り値
    関数が成功すると、0 以外の値が返る。
    関数が失敗すると、0 が返る。拡張エラー情報を取得するには、 関数を使う。
    関数が成功すると、非同期入出力(I/O)操作、つまりファイルのオーバーラップ読み取り操作が開始されます。この I/O 操作が完了した

    時点で、呼び出し側スレッドがアラート可能な待機状態でブロックされている(その先への進行を妨害されている、つまり待機している)場

    合、システムは、lpCompletionRoutine パラメータで指定した完了ルーチンを呼び出し、待機状態が完了し、ReadFileEx 関数の戻り値

    は、WAIT_IO_COMPLETION になる。
    この関数が成功し、ファイル読み取り操作が完了した時点で、呼び出し側スレッドがアラート可能な待機状態にとどまっていなかった場合、

    システムは完了ルーチンの呼び出し命令をキューに追加し、呼び出し側スレッドがアラート可能な待機状態になるのを待つ。ファイルの終わ

    り(EOF)以降を読み取ろうとすると、ReadFileEx 関数は 0 を返し、GetLastError 関数は ERROR_HANDLE_EOF を返す。

解説
    ReadFileEx 関数を使う場合、この関数が「成功」を示す値を返していても、それだけでは不十分である。GetLastError 関数を呼び出し

    て、いくつかの条件が「成功」しているだけで、把握するべき他の条件がエラーになっていないかどうかをチェックする。たとえば、

    ReadFileEx を呼び出してバッファオーバーフローが発生した場合、ReadFileEx は成功を示す、0 以外の値(TRUE)を返す。しかし、

    GetLastError は ERROR_MORE_DATA を返して、オーバーフローが発生したことを報告する。ReadFileEx 関数が成功し、待機するべ

    き条件が存在しない場合、GetLastError は ERROR_SUCCESS(操作は成功して完了しました)を返す。
    FILE_FLAG_NO_BUFFERING フラグを指定してファイルを開いた後、そのファイルの作業を行う場合、アプリケーションは次の各要件を

    満たさなければならない。
    ・ファイルアクセスは、ボリュームのセクタサイズの整数倍のバイトオフセットの位置で開始しなければならない。ボリュームのセクタサイズを判

     断するには、 GetDiskFreeSpace 関数を呼び出す。
    ・ファイルアクセスのバイト数を、ボリュームのセクタサイズの整数倍にしなければならない。たとえば、セクタサイズが 512 バイトの場合、512

     バイト、1,024 バイト、2,048 バイトの読み書きはできるが、335 バイト、981 バイト、7,171 バイトなどの読み書きはできない。
    ・読み書き操作用のバッファのアドレス(メモリ内のアドレス)を、ボリュームのセクタサイズの整数倍に整列(セクタ整列)させなければな

     らない。バッファをセクタ整列させる 1 つの方法は、 関数を使ってバッファを割り当てることである。VirtualAlloc 関数が割り当てるメモリ

     は、システムのページサイズの整数倍のアドレスに整列されている。ページサイズとボリュームのセクタサイズは両方とも 2 のべき乗なの

     で、システムのページサイズの整数倍に整列されたメモリは、ボリュームのセクタサイズの整数倍のアドレスにも整列される。
    ほかのプロセスが、hFile パラメータで指定したファイルの一部をロック(排他ロック)している場合、ReadFileEx 関数で読み取り操作を行

    うよう指定した範囲がロック済みの領域と重なっていると、この関数は失敗する。
    メールスロットからデータを読み取っているとき、バッファが小さすぎると、ReadFileEx 関数は 0(FALSE)を返し、GetLastError 関数は

    ERROR_INSUFFICIENT_BUFFER を返す。
    入力バッファを使って読み取り操作を行っている間にそのバッファにアクセスすると、そのバッファ内に読み込んだデータが壊れることがある。

    読み取り操作が完了するまでは、アプリケーションは入力バッファの読み取り、書き込み、再割り当て、解放を行ってはならない。
    未処理の非同期 I/O 要求が大量に残っている場合、ReadFileEx 関数は失敗することがある。このような障害が発生した場合、  

    GetLastError 関数は、ERROR_INVALID_USER_BUFFER または ERROR_NOT_ENOUGH_MEMORY を返すことがある。
    未処理のすべての非同期 I/O 操作を取り消すには、 CancelIo 関数を使う。この関数は、指定されたファイルハンドルに対して呼び出し側

    プロセスが発行した操作だけを取り消す。取り消された各 I/O 操作は、ERROR_OPERATION_ABORTED エラーを返して終了する。
    フロッピーディスクが入っていないフロッピーディスクドライブの読み取りを行おうとすると、システムはユーザーに対して、操作を再試行するか

    どうかを尋ねるメッセージボックスを表示する。このメッセージボックスの表示を回避するには、SEM_NOOPENFILEERRORBOX を指定し

    て関数を呼び出す。
    、、、 の各関数を使うと、アプリケーションはアラート可能な待機状態に入る。Windows 95/98:通信ポートに対して ReadFileEx 関数や

     WriteFileEx 関数を実行することはできない。しかし、ReadFile 関数と WriteFile 関数を使って非同期通信を行うことができる。