次の方法で共有


WriteFile 関数 (fileapi.h)

指定したファイルまたは入出力 (I/O) デバイスにデータを書き込みます。

この関数は、同期操作と非同期操作の両方を対象に設計されています。 非同期操作専用に設計された同様の関数については、「WriteFileEx参照してください。

構文

BOOL WriteFile(
  [in]                HANDLE       hFile,
  [in]                LPCVOID      lpBuffer,
  [in]                DWORD        nNumberOfBytesToWrite,
  [out, optional]     LPDWORD      lpNumberOfBytesWritten,
  [in, out, optional] LPOVERLAPPED lpOverlapped
);

パラメーター

[in] hFile

ファイルまたは I/O デバイスへのハンドル (ファイル、ファイル ストリーム、物理ディスク、ボリューム、コンソール バッファー、テープ ドライブ、ソケット、通信リソース、mailslot、パイプなど)。

hFile パラメーターは、書き込みアクセス権で作成されている必要があります。 詳細については、「一般的なアクセス権 およびファイル セキュリティとアクセス権のを する」を参照してください。

非同期書き込み操作の場合、hFile は、FILE_FLAG_OVERLAPPED フラグを使用して CreateFile 関数で開かれた任意のハンドル、または ソケット によって返されるソケット ハンドル、または 関数を受け入れる できます。

[in] lpBuffer

ファイルまたはデバイスに書き込むデータを格納しているバッファーへのポインター。

このバッファーは、書き込み操作の期間中有効なままである必要があります。 書き込み操作が完了するまで、呼び出し元はこのバッファーを使用しないでください。

[in] nNumberOfBytesToWrite

ファイルまたはデバイスに書き込むバイト数。

値 0 は、null 書き込み操作を指定します。 null 書き込み操作の動作は、基になるファイル システムまたは通信テクノロジによって異なります。

Windows Server 2003 および Windows XP: ネットワーク経由の パイプ書き込み操作のサイズは、書き込みごとに制限されます。 金額はプラットフォームによって異なります。 x86 プラットフォームの場合は 63.97 MB です。 x64 プラットフォームの場合、31.97 MB です。 Itanium の場合は 63.95 MB です。 パイプの詳細については、「解説」セクションを参照してください。

[out, optional] lpNumberOfBytesWritten

同期 hFile パラメーターを使用するときに書き込まれたバイト数を受け取る変数へのポインター。 WriteFile 、作業またはエラー チェックを実行する前に、この値を 0 に設定します。 このパラメーター NULL を使用すると、誤った結果を回避する非同期操作になります。

このパラメーターは、lpOverlapped パラメーターが NULLでない場合にのみ、NULL できます。

Windows 7: このパラメーターを NULLすることはできません。

詳細については、「解説」セクションを参照してください。

[in, out, optional] lpOverlapped

hFile パラメーターが FILE_FLAG_OVERLAPPEDで開かれた場合は、OVERLAPPED 構造体へのポインターが必要です。それ以外の場合は、このパラメーターを NULLできます。

バイト オフセットをサポートする hFile の場合、このパラメーターを使用する場合は、ファイルまたはデバイスへの書き込みを開始するバイト オフセットを指定する必要があります。 このオフセットは、Offset を設定し、OVERLAPPED 構造体の OffsetHigh メンバーを することによって指定します。 バイト オフセットをサポートしていない hFile の場合、オフセット と offsetHigh は無視されます。

ファイルの末尾に書き込むには、OVERLAPPED 構造体の Offset メンバーと OffsetHigh メンバーの両方を0xFFFFFFFFとして指定します。 これは、以前に CreateFile 関数を呼び出して、FILE_APPEND_DATA アクセスを使用して hFile 開くのと機能的に同じです。

lpOverlapped と FILE_FLAG_OVERLAPPEDの組み合わせの詳細については、「解説」セクションと「の同期とファイルの位置」セクション 参照してください。

戻り値

関数が成功した場合、戻り値は 0 以外 (true)。

関数が失敗した場合、または非同期的に完了している場合、戻り値は 0 (FALSE)。 拡張エラー情報を取得するには、GetLastError 関数を呼び出します。

注意GetLastError コード ERROR_IO_PENDING は失敗ではありません。これは、書き込み操作が非同期的に完了待ちであることを示します。 詳細については、「解説」を参照してください。
 

備考

WriteFile 関数は、次のいずれかの条件が発生すると返されます。

  • 要求されたバイト数が書き込まれます。
  • 読み取り操作では、パイプの読み取り側のバッファー領域が解放されます (書き込みがブロックされた場合)。 詳細については、「パイプの」セクションを参照してください。
  • 非同期ハンドルが使用されており、書き込みが非同期的に発生しています。
  • エラーが発生します。
WriteFile 関数は、未処理の非同期 I/O 要求が多すぎると、ERROR_INVALID_USER_BUFFER または ERROR_NOT_ENOUGH_MEMORY で失敗する可能性があります。

保留中のすべての非同期 I/O 操作を取り消すには、次のいずれかを使用します。

  • CancelIo—この関数は、指定されたファイル ハンドルの呼び出し元スレッドによって発行された操作のみを取り消します。
  • CancelIoEx—この関数は、指定されたファイル ハンドルに対してスレッドによって発行されたすべての操作を取り消します。
CancelSynchronousIo 関数を使用して、保留中の同期 I/O 操作を取り消します。

取り消された I/O 操作は、エラー ERROR_OPERATION_ABORTEDで完了します。

WriteFile 関数は、ERROR_NOT_ENOUGH_QUOTAで失敗する可能性があります。つまり、呼び出し元のプロセスのバッファーをページ ロックできませんでした。 詳細については、「SetProcessWorkingSetSize」を参照してください。

ファイルの一部が別のプロセスによってロックされていて、書き込み操作がロックされた部分と重複している場合、writeFile は失敗します。

ファイルに書き込む場合、書き込みに使用されるすべてのハンドルが閉じられるまで、最後の書き込み時間は完全には更新されません。 そのため、正確な最終書き込み時刻を確保するには、ファイルへの書き込みの直後にファイル ハンドルを閉じます。

書き込み操作でバッファーを使用しているときに出力バッファーにアクセスすると、そのバッファーから書き込まれたデータが破損する可能性があります。 アプリケーションは、書き込み操作が完了するまで、書き込み操作で使用されている出力バッファーへの書き込み、再割り当て、または解放を行う必要はありません。 これは、非同期ファイル ハンドルを使用する場合に特に問題になる可能性があります。 同期と非同期のファイル ハンドルに関する追加情報については、「同期とファイルの位置の の 」セクションと、同期および非同期 I/O後で確認できます。

リモート ファイルのタイムスタンプが正しく更新されない場合があることに注意してください。 一貫性のある結果を得るには、バッファーのない I/O を使用します。

システムは、書き込む 0 バイトを null 書き込み操作を指定すると解釈し、WriteFile ファイルを切り捨てたり拡張したりしません。 ファイルを切り捨てたり拡張したりするには、SetEndOfFile 関数を使用します。

writeFile を使用して、コンソール出力へのハンドル を使用して、文字を画面バッファーに書き込むことができます。 関数の正確な動作は、コンソール モードによって決まります。 データは現在のカーソル位置に書き込まれます。 書き込み操作後にカーソル位置が更新されます。 コンソール ハンドルの詳細については、「CreateFileを参照してください。

通信デバイスに書き込む場合、WriteFile の動作は、設定された現在の通信タイムアウトによって決定され、SetCommTimeouts と GetCommTimeouts 関数 使用して取得されます。 タイムアウト値の設定に失敗すると、予期しない結果が発生する可能性があります。 通信タイムアウトの詳細については、COMMTIMEOUTSを参照してください。

単一セクター書き込みはアトミックですが、トランザクションを使用しない限り、マルチセクター書き込みはアトミックであるとは限りません (つまり、作成されるハンドルはトランザクション ハンドルです。たとえば、createFileTransacted使用して作成されたハンドル)。 キャッシュされた複数セクターの書き込みが、常にディスクにすぐに書き込まれるとは限りません。そのため、CreateFileFILE_FLAG_WRITE_THROUGH を指定して、キャッシュの遅延が発生することなく、マルチセクター書き込み全体がディスクに書き込まれるようにします。

マウントされたファイル システムを持つボリュームに直接書き込む場合は、まずボリュームへの排他アクセス権を取得する必要があります。 そうしないと、アプリケーションの書き込みがファイル システムからの他の変更と競合し、ボリュームの内容が不整合な状態のままになる可能性があるため、データの破損やシステムが不安定になるリスクがあります。 これらの問題を回避するために、Windows Vista 以降で次の変更が行われています。

  • ボリューム ハンドルへの書き込みは、ボリュームにマウントされたファイル システムがない場合、または次のいずれかの条件が満たされている場合に成功します。
    • 書き込むセクターはブート セクターです。
    • ファイル システム領域の外部に存在するように書き込まれるセクター。
    • FSCTL_LOCK_VOLUME または FSCTL_DISMOUNT_VOLUMEを使用して、ボリュームを明示的にロックまたはマウント解除しました。
    • ボリュームに実際のファイル システムがありません。 (つまり、RAW ファイル システムがマウントされています)。
  • 次のいずれかの条件に該当する場合、ディスク ハンドルへの書き込みは成功します。
    • ボリュームのエクステント内に収まるように書き込まれるセクター。
    • マウントされたボリューム内に収まるように書き込まれるセクターが、FSCTL_LOCK_VOLUME または FSCTL_DISMOUNT_VOLUMEを使用してボリュームを明示的にロックまたはマウント解除しました。
    • 書き込まれるセクターは、RAW 以外のマウントされたファイル システムがないボリューム内に収まっています。
FILE_FLAG_NO_BUFFERINGを使用して CreateFile 開かれたファイルを正常に操作するための厳密な要件があります。 詳細については、「ファイル バッファリングの」を参照してください。

hFileFILE_FLAG_OVERLAPPEDで開かれた場合、次の条件が有効になります。

  • lpOverlapped パラメーターは、有効で一意の OVERLAPPED 構造体を指している必要があります。そうしないと、関数は書き込み操作が完了したことを誤って報告する可能性があります。
  • lpNumberOfBytesWritten パラメーターを NULL設定する必要があります。 書き込まれたバイト数を取得するには、GetOverlappedResult 関数を使用します。 hFile パラメーターが I/O 完了ポートに関連付けられている場合は、GetQueuedCompletionStatus 関数を呼び出すことによって書き込まれたバイト数を取得することもできます。
Windows Server 2012 では、この関数は次のテクノロジでサポートされています。
テクノロジー サポート
サーバー メッセージ ブロック (SMB) 3.0 プロトコル はい
SMB 3.0 透過的フェールオーバー (TFO) はい
SMB 3.0 とスケールアウト ファイル共有 (SO) はい
クラスター共有ボリューム ファイル システム (CsvFS) はい
回復性のあるファイル システム (ReFS) はい
 

同期とファイルの位置

FILE_FLAG_OVERLAPPEDhFile を開くと、非同期ファイル ハンドルになります。それ以外の場合は同期です。 前述のように、OVERLAPPED 構造体を使用する規則はそれぞれ若干異なります。
メモ 非同期 I/O 用にファイルまたはデバイスを開いた場合、そのハンドルを使用、WriteFile などの関数の後続の呼び出しは一般にすぐに戻りますが、ブロックされた実行に関しては同期的に動作することもできます。 詳細については、「非同期ディスク I/O が Windowsで同期として表示される」を参照してください。
 
非同期ファイル ハンドルの操作に関する考慮事項:
  • writeFile 書き込み操作が完了する前に返される場合があります。 このシナリオでは、WriteFile は FALSE 返し、GetLastError 関数は ERROR_IO_PENDINGを返します。これにより、システムが書き込み操作を完了している間も呼び出しプロセスを続行できます。
  • lpOverlapped パラメーターは NULL することはできません。また、次の点を念頭に置いて使用してください。
    • OVERLAPPED 構造体で指定されたイベントはシステムによって自動的に設定およびリセットされますが、OVERLAPPED 構造体で指定されたオフセットは自動的に更新されません。
    • WriteFile は、I/O 操作の開始時にイベントを非署名状態にリセットします。
    • OVERLAPPED 構造体で指定されたイベントは、書き込み操作が完了するとシグナル状態に設定されます。その時点まで、書き込み操作は保留中と見なされます。
    • 書き込み操作は、OVERLAPPED 構造体で指定されたオフセットから開始され、システム レベルの書き込み操作が完了する前に writeFile が返される可能性があるため (書き込み保留中)、オフセットも構造体の他の部分も、イベントが通知されるまでアプリケーションによって変更、解放、または再利用されることはありません 書き込みが完了しました)。
同期ファイル ハンドルの操作に関する考慮事項:
  • lpOverlapped が NULL場合、書き込み操作は現在のファイル位置から開始され、WriteFile は操作が完了するまで戻らず、WriteFile が戻る前にファイル ポインター 更新されます。
  • lpOverlapped NULLされていない場合、書き込み操作は、OVERLAPPED 構造体で指定されたオフセットから開始され、書き込み操作が完了するまで WriteFile 戻りません。 システムは、WriteFile が返 前に、internal フィールドと InternalHigh フィールドとファイル ポインター OVERLAPPED を更新します。
詳細については、「CreateFile
と同期および非同期 I/Oする」を参照してください。

パイプ

匿名パイプが使用されていて、読み取りハンドルが閉じられている場合、WriteFile がパイプの対応する書き込みハンドルを使用して書き込みを試行すると、関数は FALSE
返し、GetLastError ERROR_BROKEN_PIPEを返します。

アプリケーションが WriteFile 関数を使用してパイプに書き込むときにパイプ バッファーがいっぱいになると、書き込み操作がすぐに完了しない可能性があります。 書き込み操作は、読み取り操作 (ReadFile 関数を使用) によって、パイプに使用できるシステム バッファー領域が増えたときに完了します。

バッファー領域が不足している非ブロッキングバイト モードのパイプ ハンドルに書き込む場合、writeFile は、nNumberOfBytesToWrite*lpNumberOfBytesWritten TRUE を返します。

パイプの詳細については、「パイプを する」を参照してください。

トランザクション操作の

ファイル ハンドルにバインドされたトランザクションがある場合、ファイル書き込みはトランザクションされます。 詳細については、「トランザクション NTFSについて」を参照してください。

例については、「一時ファイル の作成と使用」および「の読み取りまたは書き込みのためにファイルを開く 」を参照してください。

次の C++ の例は、バッファーのないファイル書き込み用にセクターを調整する方法を示しています。 Size 変数は、ファイルへの書き込みに関心のある元のデータ ブロックのサイズです。 バッファーされていないファイル I/O に関するその他の規則については、「ファイル バッファリングの」を参照してください。
#include <windows.h>

#define ROUND_UP_SIZE(Value,Pow2) ((SIZE_T) ((((ULONG)(Value)) + (Pow2) - 1) & (~(((LONG)(Pow2)) - 1))))

#define ROUND_UP_PTR(Ptr,Pow2)  ((void *) ((((ULONG_PTR)(Ptr)) + (Pow2) - 1) & (~(((LONG_PTR)(Pow2)) - 1))))

int main()
{
   // Sample data
   unsigned long bytesPerSector = 65536; // obtained from the GetFreeDiskSpace function.
   unsigned long size = 15536; // Buffer size of your data to write.
   
   // Ensure you have one more sector than Size would require.
   size_t sizeNeeded = bytesPerSector + ROUND_UP_SIZE(size, bytesPerSector);
   
   // Replace this statement with any allocation routine.
   auto buffer = new uint8_t[SizeNeeded];
   
   // Actual alignment happens here.
   auto bufferAligned = ROUND_UP_PTR(buffer, bytesPerSector);

   // ... Add code using bufferAligned here.
   
   // Replace with corresponding free routine.
   delete buffer;
}

必要条件

要件 価値
サポートされる最小クライアント Windows XP [デスクトップ アプリ |UWP アプリ]
サポートされる最小サーバー Windows Server 2003 [デスクトップ アプリ |UWP アプリ]
ターゲット プラットフォーム の ウィンドウズ
ヘッダー fileapi.h (Windows.h を含む)
ライブラリ Kernel32.lib
DLL Kernel32.dll

関連項目

CancelIo を する

CancelIoEx を する

CancelSynchronousIo の

CreateFile の

CreateFileTransacted の

ファイル管理機能の

GetLastError の

GetOverlappedResult の

GetQueuedCompletionStatus を する

ReadFile の

SetEndOfFile の

WriteFileEx の