ReadFile 函式 (fileapi.h)
從指定的檔案或輸入/輸出 (I/O) 裝置讀取資料。 如果裝置支援,讀取就會發生在檔案指標所指定的位置。
此函式是針對同步和非同步作業所設計。 如需專為非同步作業而設計的類似函式,請參閱 ReadFileEx。
語法
BOOL ReadFile(
[in] HANDLE hFile,
[out] LPVOID lpBuffer,
[in] DWORD nNumberOfBytesToRead,
[out, optional] LPDWORD lpNumberOfBytesRead,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
參數
[in] hFile
裝置的控制碼 (例如,檔案、檔案資料流程、實體磁片、磁片區、主控台緩衝區、磁帶機、通訊端、通訊資源、郵件集或管道) 。
hFile參數必須已使用讀取權限建立。 如需詳細資訊,請參閱 一般存取權限 和 檔案安全性和存取權限。
針對非同步讀取作業,hFile可以是使用 CreateFile函式以 FILE_FLAG_OVERLAPPED旗標開啟的任何控制碼,或是通訊端或accept函式所傳回的通訊端控制碼。
[out] lpBuffer
緩衝區的指標,接收從檔案或裝置讀取的資料。
此緩衝區在讀取作業期間必須維持有效狀態。 呼叫端在讀取作業完成之前,不得使用此緩衝區。
[in] nNumberOfBytesToRead
要讀取的位元組數目上限。
[out, optional] lpNumberOfBytesRead
使用同步 hFile 參數時,接收讀取位元組數目之變數的指標。 ReadFile 會將此值設定為零,再進行任何工作或錯誤檢查。 如果這是非同步作業,以避免發生錯誤的結果,請使用 Null 作為此參數。
只有當lpOverlapped參數不是Null時,此參數才能為Null。
Windows 7: 此參數不可為 Null。
如需詳細資訊,請參閱<備註>一節。
[in, out, optional] lpOverlapped
如果hFile參數是以FILE_FLAG_OVERLAPPED開啟,則需要重迭結構的指標,否則可以是Null。
如果使用FILE_FLAG_OVERLAPPED開啟hFile,則 lpOverlapped參數必須指向有效的唯一重迭結構,否則函式可能會錯誤地報告讀取作業已完成。
對於支援位元組位移的 hFile ,如果您使用此參數,您必須指定要從檔案或裝置開始讀取的位元組位移。 此位移是藉由設定OVERLAPPED結構的Offset和OffsetHigh成員來指定。 若為不支援位元組位移的 hFile ,則會忽略 Offset 和 OffsetHigh 。
For more information about different combinations of lpOverlapped and FILE_FLAG_OVERLAPPED, see the Remarks section and the Synchronization and File Position section.
傳回值
如果函式成功,則傳回值為非零 (TRUE) 。
如果函式失敗或以非同步方式完成,傳回值會是零 (FALSE) 。 若要取得擴充的錯誤資訊,請呼叫 GetLastError 函式。
備註
ReadFile函式會在發生下列其中一個情況時傳回:
- 已讀取要求的位元組數目。
- 寫入作業會在管道的寫入端完成。
- 正在使用非同步控制碼,且讀取是以非同步方式發生。
- 發生錯誤。
每當有太多未處理的非同步 I/O 要求時, ReadFile 函式可能會因為 ERROR_INVALID_USER_BUFFER 或 ERROR_NOT_ENOUGH_MEMORY 而失敗。
若要取消所有擱置的非同步 I/O 作業,請使用:
- CancelIo — 此函式只會取消所指定檔案控制碼的呼叫執行緒所發出的作業。
- CancelIoEx— 此函式會取消執行緒針對指定的檔案控制代碼發出的所有作業。
使用 CancelSynchronousIo 取消暫止的同步 I/O 作業。
取消的 I/O 作業已完成,錯誤 ERROR_OPERATION_ABORTED。
ReadFile函式可能會因為ERROR_NOT_ENOUGH_QUOTA而失敗,這表示呼叫程式的緩衝區無法鎖定頁面。 如需詳細資訊,請參閱 SetProcessWorkingSetSize。
如果檔案的一部分被另一個進程鎖定,且讀取作業與鎖定的部分重迭,則此函式會失敗。
當讀取作業使用緩衝區時存取輸入緩衝區,可能會導致讀取到該緩衝區的資料損毀。 應用程式不得從讀取作業讀取、寫入、重新配置或釋放讀取作業所使用的輸入緩衝區,直到讀取作業完成為止。 使用非同步檔案控制碼時,這特別有問題。 如需同步與非同步檔案控制代碼的其他資訊,請參閱 同步處理和檔案位置 一節和 CreateFile 參考主題。
您可以使用 ReadFile 搭配主控台輸入控制碼,從主控台輸入緩衝區讀取字元。 主控台模式會決定 ReadFile 函式的確切行為。 根據預設,主控台模式 會ENABLE_LINE_INPUT,這表示 ReadFile 應該讀取直到到達歸位字元為止。 如果您按下 Ctrl+C,呼叫會成功,但 GetLastError 會傳回 ERROR_OPERATION_ABORTED。 如需詳細資訊,請參閱 CreateFile。
從通訊裝置讀取時,ReadFile的行為是由目前通訊逾時所決定,方法是使用SetCommTimeouts 和 GetCommTimeouts函式來設定和擷取。 如果您無法設定逾時值,可能會發生無法預測的結果。 如需通訊逾時的詳細資訊,請參閱 COMMTIMEOUTS。
如果 ReadFile 嘗試從具有太小緩衝區的郵件集讀取,則函式會傳回 FALSE ,而 GetLastError 會傳回 ERROR_INSUFFICIENT_BUFFER。
使用FILE_FLAG_NO_BUFFERING旗標,成功使用CreateFile開啟的檔案有嚴格的需求。 如需詳細資訊,請參閱 檔案緩衝處理。
如果使用FILE_FLAG_OVERLAPPED開啟hFile,下列條件會生效:
- lpOverlapped參數必須指向有效且唯一的OVERLAPPED結構,否則函式可能會錯誤地報告讀取作業已完成。
- lpNumberOfBytesRead參數應設定為Null。 使用 GetOverlappedResult 函式來取得讀取的實際位元組數目。 如果 hFile 參數與 I/O 完成埠相關聯,您也可以呼叫 GetQueuedCompletionStatus 函式來取得讀取的位元組數目。
同步處理和檔案位置
如果 hFile 是以 FILE_FLAG_OVERLAPPED開啟,則它是非同步檔案控制代碼;否則為同步。 使用 OVERLAPPED 結構的規則會針對每個結構稍有不同,如先前所述。- ReadFile 可能會在讀取作業完成之前傳回。 在此案例中, ReadFile 會傳回 FALSE ,而 GetLastError 函式會 傳回ERROR_IO_PENDING,這可讓呼叫進程在系統完成讀取作業時繼續。
- lpOverlapped參數不得為Null,而且應該與下列事實搭配使用:
- 雖然系統會自動設定並重設 重迭 結構中指定的事件,但 重 迭結構中指定的位移不會自動更新。
- ReadFile 會在事件開始 I/O 作業時,將事件重設為非簽署狀態。
- 在重迭結構中指定的事件會在讀取作業完成時設定為訊號狀態;直到該時間為止,讀取作業會被視為擱置中。
- 由於讀取作業會從 重迭 結構中指定的位移開始,而且 ReadFile 可能會在系統層級讀取作業完成之前傳回, (讀取擱置) ,因此,除非應用程式發出訊號,否則應用程式不應修改、釋放或重複使用結構的任何其他部分,否則不會修改、釋放或重複使用該結構的位移,直到事件發出訊號 (, 讀取完成) 。
- 如果在非同步作業期間偵測到檔案結尾 (EOF) ,該作業的 GetOverlappedResult 呼叫會傳回 FALSE ,而 GetLastError 會傳回 ERROR_HANDLE_EOF。
- 如果 lpOverlapped 為 Null,讀取作業會從目前的檔案位置開始, 而且 ReadFile 在作業完成之前不會傳回,而且系統會在 ReadFile 傳回之前更新檔案指標。
- 如果 lpOverlapped 不是 Null,讀取作業會從 重 迭結構中指定的位移開始, 而 ReadFile 不會在讀取作業完成之前傳回。 系統會在ReadFile傳回之前更新OVERLAPPED位移和檔案指標。
- 如果 lpOverlapped 為 Null,則當同步讀取作業到達檔案結尾時, ReadFile 會傳回 TRUE ,並將 設定
*lpNumberOfBytesRead
為零。 - 如果 lpOverlapped 不是 Null,則當同步讀取作業到達檔案結尾時, ReadFile 會傳回 FALSE ,而 GetLastError 會傳回 ERROR_HANDLE_EOF。
管道
如果使用匿名管道且寫入控制碼已經關閉,當 ReadFile 嘗試使用管道的對應讀取控制碼進行讀取時,函式會傳回 FALSE ,而 GetLastError 會傳回 ERROR_BROKEN_PIPE。如果在訊息模式中讀取具名管道,且下一則訊息超過 nNumberOfBytesToRead 參數指定, ReadFile 會傳回 FALSE , 而 GetLastError 會傳回 ERROR_MORE_DATA。 後續呼叫 ReadFile 或 PeekNamedPipe 函式可以讀取訊息的其餘部分。
如果當 ReadFile在管道上傳回TRUE時,lpNumberOfBytesRead參數為零,則管道的另一端會呼叫WriteFile函式,並將nNumberOfBytesToWrite設定為零。
如需管道的詳細資訊,請參閱 管道。
交易作業
如果有系結至檔案控制代碼的交易,則函式會從檔案的交易檢視傳回資料。 交易讀取控制碼保證會在控制碼期間顯示檔案的相同檢視。 如需詳細資訊,請參閱 關於交易式 NTFS。在 Windows 8 和 Windows Server 2012 中,下列技術支援此函式。
技術 | 支援 |
---|---|
伺服器訊息區 (SMB) 3.0 通訊協定 | 是 |
SMB 3.0 透明容錯移轉 (TFO) | 是 |
具有向外延展檔案共用的 SMB 3.0 (SO) | 是 |
叢集共用磁片區檔案系統 (CsvFS) | 是 |
彈性檔案系統 (ReFS) | 是 |
範例
如需示範如何測試檔案尾的程式碼範例,請參閱 測試檔案尾。 如需其他範例,請參閱 建立和使用暫存檔 和 開啟檔案以供讀取或寫入。
需求
最低支援的用戶端 | Windows XP [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | fileapi.h (包含 Windows.h) |
程式庫 | Kernel32.lib |
DLL | Kernel32.dll |