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

要寫入檔案或裝置的位元元組數目。

值為零會指定 Null 寫入作業。 Null 寫入作業的行為取決於基礎文件系統。

網路上的管道寫入作業限制為每個寫入 65,535 個字節。 如需管道的詳細資訊,請參閱一節。

[in, out] lpOverlapped

重疊 (異步) 寫入作業期間,提供要使用的重疊數據結構的 重疊 數據結構指標。

對於支援位元組位移的檔案,您必須指定要開始寫入檔案的位元移。 您可以藉由設定 OVERLAPPED 結構的 OffsetOffsetHigh 成員來指定此位移。 對於不支援位元組位移的檔案或裝置,會忽略 OffsetOffsetHigh

若要寫入檔案結尾,請將 OFFSETOffsetHigh 結構的成員指定為 。0xFFFFFFFF 這在功能上相當於先前呼叫 CreateFile 函式,以使用 FILE_APPEND_DATA 存取來開啟 hFile

WriteFileEx 函式會忽略重疊結構的 hEvent 成員。 應用程式在 WriteFileEx 呼叫的內容中,可以自由使用該成員作為自己的用途。 WriteFileEx 會藉由呼叫 或佇列呼叫 來發出寫入作業完成的訊號,也就是 lpCompletionRoutine 所指向的完成例程,因此不需要事件句柄。

WriteFileEx 函式會使用 OVERLAPPED 結構的 InternalInternalHigh 成員。 您不應該變更這些成員的值。

OVERLAPPED 數據結構在寫入作業期間必須維持有效狀態。 它不應該是可在寫入作業擱置完成時超出範圍的變數。

[in] lpCompletionRoutine

當寫入作業完成且呼叫線程處於可警示的等候狀態時,要呼叫的完成例程指標。 如需此完成例程的詳細資訊,請參閱 FileIOCompletionRoutine

傳回值

如果函式成功,則傳回非零的值。

如果此函式失敗,則傳回值為零。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

如果 WriteFileEx 函式成功,則呼叫線程會有異步 I/O 作業擱置中:檔案的重疊寫入作業。 當此 I/O 作業完成,且呼叫線程處於可警示的等候狀態時,操作系統會呼叫 lpCompletionRoutine 所指向的函式,而等候會以 的 WAIT_IO_COMPLETION傳回碼完成。

如果函式成功且檔案寫入作業完成,但呼叫線程未處於可警示的等候狀態,系統會將呼叫排入 *lpCompletionRoutine 的佇列,直到呼叫線程進入可警示的等候狀態為止。 如需可警示的等候狀態和重疊輸入/輸出作業的詳細資訊,請參閱 關於同步處理

備註

使用 WriteFileEx 時,即使函式傳回「成功」,還是應該檢查 GetLastError ,以檢查 是否成功 ,但有一些您可能想要知道的結果。 例如,呼叫 WriteFileEx 時的緩衝區溢位會傳回 TRUE,但 GetLastError 會以 ERROR_MORE_DATA回報溢位。 如果函式呼叫成功且沒有警告條件, GetLastError 會傳回 ERROR_SUCCESS

如果 hFile 參數與 I/O 完成埠相關聯,WriteFileEx 函式將會失敗。 若要使用這種類型的句柄執行寫入,請使用 WriteFile 函式。

如果有太多未處理的異步 I/O 要求, WriteFileEx 函式可能會失敗。 發生這類失敗時, GetLastError 可以傳回 ERROR_INVALID_USER_BUFFERERROR_NOT_ENOUGH_MEMORY

若要取消所有擱置的異步 I/O 作業,請使用:

  • CancelIo:此函式只會取消所指定檔案句柄的呼叫線程所發出的作業。
  • CancelIoEx:此函式會取消線程針對指定的檔句柄發出的所有作業。

使用 CancelSynchronousIo 取消暫止的同步 I/O 作業。

取消的 I/O 作業已完成,錯誤 ERROR_OPERATION_ABORTED

如果 hFile 所指定的檔案部分被另一個進程鎖定,而指定的寫入作業會與鎖定的部分重疊, WriteFileEx 會失敗。

寫入檔案時,上次寫入時間不會完全更新,直到所有用於寫入的句柄都已關閉為止。 因此,若要確保上次寫入時間正確,請在寫入檔案之後立即關閉檔案句柄。

當寫入作業使用緩衝區時存取輸出緩衝區,可能會導致從該緩衝區寫入的數據損毀。 應用程式不得寫入、重新配置或釋放寫入作業所使用的輸出緩衝區,直到寫入作業完成為止。

請注意,遠端檔案可能無法正確更新時間戳。 若要確保結果一致,請使用未緩衝的 I/O。

系統會將零個字節解譯為寫入,以指定 Null 寫入作業, 而 WriteFile 不會截斷或擴充檔案。 若要截斷或擴充檔案,請使用 SetEndOfFile 函式。

應用程式會使用 WaitForSingleObjectExWaitForMultipleObjectsExMsgWaitForMultipleObjectsExSignalObjectAndWaitSleepEx 函式來進入可警示的等候狀態。 如需可警示的等候狀態和重疊 I/O 作業的詳細資訊,請參閱 關於同步處理

如果您直接寫入具有掛接文件系統的磁碟區,您必須先取得磁碟區的獨佔存取權。 否則,您有造成數據損毀或系統不穩定的風險,因為應用程式的寫入可能會與其他來自檔系統的變更衝突,並將磁碟區的內容保持不一致的狀態。 若要避免這些問題,Windows Vista 和更新版本中已進行下列變更:

  • 如果磁碟區沒有掛接的文件系統,或下列其中一個條件成立,磁碟區句柄上的寫入將會成功:
    • 要寫入的扇區是開機扇區。
    • 要寫入的扇區位於文件系統空間之外。
    • 您已使用 FSCTL_LOCK_VOLUMEFSCTL_DISMOUNT_VOLUME明確鎖定或卸載磁碟區。
    • 磁碟區沒有實際的文件系統。 (換句話說,它已掛接 RAW 文件系統。)
  • 如果下列其中一個條件成立,磁碟句柄上的寫入將會成功:
    • 要寫入的扇區不會落在磁碟區的範圍內。
    • 要寫入的扇區落在掛接的磁碟區內,但您已使用 FSCTL_LOCK_VOLUMEFSCTL_DISMOUNT_VOLUME明確鎖定或卸除磁碟區。
    • 要寫入的扇區落在未掛接文件系統的磁碟區中,而不是RAW。

使用 FILE_FLAG_NO_BUFFERING,成功使用 CreateFile 開啟的檔案有嚴格的需求。 如需詳細資訊,請參閱 檔案緩衝處理。

在 Windows 8 和 Windows Server 2012 中,下列技術支援此函式。

技術 支援
伺服器消息塊 (SMB) 3.0 通訊協定 Yes
SMB 3.0 透明故障轉移 (TFO) Yes
具有向外延展檔案共用的SMB 3.0 (SO) Yes
叢集共用磁碟區文件系統 (CsvFS) Yes
彈性檔案系統 (ReFS) Yes

交易作業

如果有系結至檔句柄的交易,則會交易檔案寫入。 如需詳細資訊,請參閱 關於交易式NTFS

範例

如需範例,請參閱 使用完成例程的命名管道伺服器

規格需求

需求
最低支援的用戶端 Windows XP [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 fileapi.h (包含 Windows.h)
程式庫 Kernel32.lib
DLL Kernel32.dll

另請參閱