WriteFileEx 関数 (fileapi.h)
指定したファイルまたは入出力 (I/O) デバイスにデータを書き込みます。 書き込みが完了するか取り消され、呼び出し元のスレッドがアラート可能な状態にあるときに、指定した完了ルーチンが呼び出され、その完了状態が非同期的に報告されます。
ファイルまたはデバイスにデータを同期的に書き込むには、 WriteFile 関数を使用します。
構文
BOOL WriteFileEx(
[in] HANDLE hFile,
[in, optional] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[in, out] LPOVERLAPPED lpOverlapped,
[in] LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
パラメーター
[in] hFile
ファイルまたは I/O デバイスへのハンドル (ファイル、ファイル ストリーム、物理ディスク、ボリューム、コンソール バッファー、テープ ドライブ、ソケット、通信リソース、mailslot、パイプなど)。
このパラメーターには、CreateFile 関数によって FILE_FLAG_OVERLAPPED フラグで開かれた任意のハンドル、またはソケットまたは accept 関数によって返されるソケット ハンドルを指定できます。
I/O 入力候補ポートをこのハンドルに関連付けないでください。 詳細については、「解説」を参照してください。
このハンドルには、 GENERIC_WRITE アクセス権も必要です。 アクセス権の詳細については、「 ファイル セキュリティとアクセス権」を参照してください。
[in, optional] lpBuffer
ファイルまたはデバイスに書き込まれるデータを含むバッファーへのポインター。
このバッファーは、書き込み操作の間は有効なままである必要があります。 書き込み操作が完了するまで、呼び出し元はこのバッファーを使用しないでください。
[in] nNumberOfBytesToWrite
ファイルまたはデバイスに書き込まれるバイト数。
値 0 は、null 書き込み操作を指定します。 null 書き込み操作の動作は、基になるファイル システムによって異なります。
ネットワーク全体のパイプ書き込み操作は、書き込みあたり 65,535 バイトに制限されます。 パイプの詳細については、「解説」セクションを参照してください。
[in, out] lpOverlapped
重なり合った (非同期) 書き込み操作中に使用されるデータを提供する OVERLAPPED データ構造へのポインター。
バイト オフセットをサポートするファイルの場合は、ファイルへの書き込みを開始するバイト オフセットを指定する必要があります。 このオフセットを指定するには、OVERLAPPED 構造体の Offset メンバーと OffsetHigh メンバーを設定します。 バイト オフセットをサポートしていないファイルまたはデバイスの場合、 Offset と OffsetHigh は無視されます。
ファイルの末尾に書き込むには、OVERLAPPED 構造体の Offset メンバーと OffsetHigh メンバーの両方を として0xFFFFFFFF
指定します。 これは、以前に CreateFile 関数を呼び出して、FILE_APPEND_DATA アクセスを使用して hFile を開いた場合と機能的に同じです。
WriteFileEx 関数は、OVERLAPPED 構造体の hEvent メンバーを無視します。 アプリケーションは、 WriteFileEx 呼び出しのコンテキストで、そのメンバーを独自の目的で自由に使用できます。 WriteFileEx は、 lpCompletionRoutine によって指される完了ルーチンを呼び出すか、呼び出しをキューに入れるという方法で書き込み操作の完了を通知するため、イベント ハンドルは必要ありません。
WriteFileEx 関数は、OVERLAPPED 構造体の Internal メンバーと InternalHigh メンバーを使用します。 これらのメンバーの値は変更しないでください。
OVERLAPPED データ構造は、書き込み操作の間は有効なままである必要があります。 書き込み操作が完了待ちの間にスコープ外に出ることができる変数にすることはできません。
[in] lpCompletionRoutine
書き込み操作が完了し、呼び出し元スレッドが警告可能な待機状態のときに呼び出される完了ルーチンへのポインター。 この完了ルーチンの詳細については、「 FileIOCompletionRoutine」を参照してください。
戻り値
関数が成功すると、戻り値は 0 以外になります。
関数が失敗した場合は、0 を返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。
WriteFileEx 関数が成功した場合、呼び出し元スレッドには非同期 I/O 操作が保留中です。ファイルへの書き込み操作が重複しています。 この I/O 操作が完了し、呼び出し元のスレッドが警告可能な待機状態でブロックされると、オペレーティング システムは lpCompletionRoutine が指す関数を呼び出し、待機は のリターン コード WAIT_IO_COMPLETION
で完了します。
関数が成功し、ファイル書き込み操作が完了したが、呼び出し元のスレッドが警告可能な待機状態でない場合、システムは呼び出し元のスレッドがアラート可能な待機状態になるまで呼び出しを保持して、*lpCompletionRoutine への呼び出しをキューに入れます。 アラート可能な待機状態と重複する入出力操作の詳細については、「 同期について」を参照してください。
注釈
WriteFileEx を使用する場合は、関数が "success" を返しても GetLastError をチェックして、成功したが、知りたい結果がある条件をチェックする必要があります。 たとえば、 WriteFileEx を呼び出すときのバッファー オーバーフローは を返 TRUE
しますが、 GetLastError は でオーバーフロー ERROR_MORE_DATA
を報告します。 関数呼び出しが成功し、警告条件がない場合、 GetLastError は を返します ERROR_SUCCESS
。
hFile パラメーターが I/O 入力候補ポートに関連付けられている場合、WriteFileEx 関数は失敗します。 この種類のハンドルを使用して書き込みを実行するには、 WriteFile 関数を使用します。
未処理の非同期 I/O 要求が多すぎると 、WriteFileEx 関数が失敗する可能性があります。 このようなエラーが発生した場合、GetLastError は または ERROR_NOT_ENOUGH_MEMORY
を返ERROR_INVALID_USER_BUFFER
すことができます。
保留中のすべての非同期 I/O 操作を取り消すには、次のいずれかを使用します。
- CancelIo: この関数は、指定されたファイル ハンドルの呼び出し元スレッドによって発行された操作のみを取り消します。
- CancelIoEx: この関数は、指定されたファイル ハンドルに対してスレッドによって発行されたすべての操作を取り消します。
保留中の同期 I/O 操作を取り消すには、CancelSynchronousIo を使用します。
取り消された I/O 操作は、エラー ERROR_OPERATION_ABORTEDで完了します。
hFile で指定されたファイルの一部が別のプロセスによってロックされていて、指定された書き込み操作がロックされた部分と重複している場合、WriteFileEx は失敗します。
ファイルに書き込む場合、書き込みに使用されるすべてのハンドルが閉じられるまで、最後の書き込み時刻は完全には更新されません。 したがって、正確な最終書き込み時刻を確保するには、ファイルへの書き込みの直後にファイル ハンドルを閉じます。
書き込み操作でバッファーを使用しているときに出力バッファーにアクセスすると、そのバッファーから書き込まれたデータが破損する可能性があります。 アプリケーションは、書き込み操作が完了するまで、書き込み操作で使用されている出力バッファーに対する書き込み、再割り当て、または解放を行う必要はありません。
リモート ファイルのタイム スタンプが正しく更新されない場合があることに注意してください。 一貫性のある結果を得るには、バッファーなしの I/O を使用します。
システムは、書き込む 0 バイトを null 書き込み操作として解釈し、 WriteFile はファイルを切り捨てたり拡張したりしません。 ファイルを切り捨てるか拡張するには、 SetEndOfFile 関数を使用します。
アプリケーションでは 、WaitForSingleObjectEx、 WaitForMultipleObjectsEx、 MsgWaitForMultipleObjectsEx、 SignalObjectAndWait、 SleepEx 関数を使用して、アラート可能な待機状態を入力します。 アラート可能な待機状態と重複する I/O 操作の詳細については、「 同期について」を参照してください。
マウントされたファイル システムを持つボリュームに直接書き込む場合は、まずボリュームへの排他アクセス権を取得する必要があります。 そうしないと、アプリケーションの書き込みがファイル システムからの他の変更と競合し、ボリュームの内容が不整合な状態のままになる可能性があるため、データの破損やシステムの不安定を引き起こすリスクがあります。 これらの問題を回避するために、Windows Vista 以降で次の変更が行われています。
- ボリュームにマウントされたファイル システムがない場合、または次のいずれかの条件が満たされている場合、ボリューム ハンドルに対する書き込みは成功します。
- 書き込むセクターはブート セクターです。
- 書き込み対象のセクターは、ファイル・システム・スペースの外部に存在します。
- FSCTL_LOCK_VOLUMEまたはFSCTL_DISMOUNT_VOLUMEを使用して、ボリュームを明示的にロックまたはマウント解除しました。
- ボリュームには実際のファイル システムがありません。 (つまり、RAW ファイル システムがマウントされています)。
- 次のいずれかの条件に該当する場合、ディスク ハンドルへの書き込みは成功します。
- 書き込まれるセクターは、ボリュームのエクステント内に含まれません。
- マウントされたボリューム内に収まるように書き込まれるセクターが、 FSCTL_LOCK_VOLUME または FSCTL_DISMOUNT_VOLUMEを使用してボリュームを明示的にロックまたはマウント解除しました。
- 書き込まれるセクターは、RAW 以外のマウントされたファイル システムがないボリューム内に含まれます。
FILE_FLAG_NO_BUFFERINGを使用して CreateFile で開かれたファイルを正常に操作するための厳密な要件があります。 詳細については、「 ファイルバッファリング」を参照してください。
Windows 8 と Windows Server 2012 では、この関数は、次のテクノロジによってサポートされています。
テクノロジ | サポートされています |
---|---|
サーバー メッセージ ブロック (SMB) 3.0 プロトコル | はい |
SMB 3.0 Transparent Failover (TFO) | はい |
スケールアウト ファイル共有 (SO) を使う SMB 3.0 | はい |
クラスターの共有ボリューム ファイル システム (CsvFS) | はい |
Resilient File System (ReFS) | はい |
Transacted Operations
ファイル ハンドルにバインドされたトランザクションがある場合、ファイルの書き込みはトランザクション処理対象です。 詳細については、「 トランザクション NTFS について」を参照してください。
例
例については、「 完了ルーチンを使用した名前付きパイプ サーバー」を参照してください。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP [デスクトップ アプリ | UWP アプリ] |
サポートされている最小のサーバー | Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ] |
対象プラットフォーム | Windows |
ヘッダー | fileapi.h (Windows.h を含む) |
Library | Kernel32.lib |
[DLL] | Kernel32.dll |