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 結構的 Offset 和 OffsetHigh 成員來指定此位移。 對於不支援位元組位移的檔案或裝置,會忽略 Offset 和 OffsetHigh 。
若要寫入檔案結尾,請將 OFFSET 和 OffsetHigh 結構的成員指定為 。0xFFFFFFFF
這在功能上相當於先前呼叫 CreateFile 函式,以使用 FILE_APPEND_DATA 存取來開啟 hFile。
WriteFileEx 函式會忽略重疊結構的 hEvent 成員。 應用程式在 WriteFileEx 呼叫的內容中,可以自由使用該成員作為自己的用途。 WriteFileEx 會藉由呼叫 或佇列呼叫 來發出寫入作業完成的訊號,也就是 lpCompletionRoutine 所指向的完成例程,因此不需要事件句柄。
WriteFileEx 函式會使用 OVERLAPPED 結構的 Internal 和 InternalHigh 成員。 您不應該變更這些成員的值。
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_BUFFER
或 ERROR_NOT_ENOUGH_MEMORY
。
若要取消所有擱置的異步 I/O 作業,請使用:
- CancelIo:此函式只會取消所指定檔案句柄的呼叫線程所發出的作業。
- CancelIoEx:此函式會取消線程針對指定的檔句柄發出的所有作業。
使用 CancelSynchronousIo 取消暫止的同步 I/O 作業。
取消的 I/O 作業已完成,錯誤 ERROR_OPERATION_ABORTED。
如果 hFile 所指定的檔案部分被另一個進程鎖定,而指定的寫入作業會與鎖定的部分重疊, WriteFileEx 會失敗。
寫入檔案時,上次寫入時間不會完全更新,直到所有用於寫入的句柄都已關閉為止。 因此,若要確保上次寫入時間正確,請在寫入檔案之後立即關閉檔案句柄。
當寫入作業使用緩衝區時存取輸出緩衝區,可能會導致從該緩衝區寫入的數據損毀。 應用程式不得寫入、重新配置或釋放寫入作業所使用的輸出緩衝區,直到寫入作業完成為止。
請注意,遠端檔案可能無法正確更新時間戳。 若要確保結果一致,請使用未緩衝的 I/O。
系統會將零個字節解譯為寫入,以指定 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 通訊協定 | 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 |