Windows API一日一练(54)WriteFile和ReadFile函数

Post date: 2012/3/27 上午 07:36:37

分類: Direct3D2007-10-21 10:09 29788人閱讀 評論(16) 收藏 舉報

讀寫文件是每個Windows軟件開發人員都需要做的工作。可見這項工作是非常重要的,畢竟各種各樣的數據都需要保存起來,以便作各種各樣的分析,或者通過網絡傳送給別人。像大家用BT下載的電影,在那個BT軟件裡,就需要不斷從網絡裡接收到數據,然後再把這些數據保存到文件裡合適的位置,就可以生成跟發行者那裡一樣的文件,這樣才可以播放出來。又比如我在玩《征途》的遊戲裡,剛剛打開遊戲時,它就不斷從服務器上下載更新的文件下來,然後保存到硬盤。WriteFile函數是用來寫數據到文件,ReadFile函數是從文件裡讀取數據出來。但這兩個函數不但可以讀取寫磁盤的文件,也可以接收和發送網絡的數據,還有讀寫串口、USB、並口等設備的數據。在讀寫文件裡,首先就是先打開文件,然後判斷打開是否成功。在寫文件時,同時要注意磁盤的空間是否滿等問題。在讀取文件時,往往需要讀取不同位置的文件,比如要讀取一個4G的視頻文件,就不可能完全把它讀取到內存裡,因此就需要對文件進行定位讀取。

函數WriteFile和ReadFile聲明如下:

WINBASEAPI

BOOL

WINAPI

WriteFile(

__in HANDLE hFile,

__in_bcount(nNumberOfBytesToWrite) LPCVOID lpBuffer,

__in DWORD nNumberOfBytesToWrite,

__out_opt LPDWORD lpNumberOfBytesWritten,

__inout_opt LPOVERLAPPED lpOverlapped

);

WINBASEAPI

BOOL

WINAPI

ReadFile(

__in HANDLE hFile,

__out_bcount_part(nNumberOfBytesToRead, *lpNumberOfBytesRead) LPVOID lpBuffer,

__in DWORD nNumberOfBytesToRead,

__out_opt LPDWORD lpNumberOfBytesRead,

__inout_opt LPOVERLAPPED lpOverlapped

);

hFile是文件句柄。

lpBuffer是讀寫數據緩衝區。

nNumberOfBytesToWrite是多少數據要寫入。

lpNumberOfBytesWritten是已經寫入多少數據。

nNumberOfBytesToRead是多少數據要讀取。

nNumberOfBytesToRead是已經讀取多少數據。

lpOverlapped是異步讀寫的結構。

調用函數的例子如下:

#001 //創建、寫入、讀取文件。

#002 //蔡軍生 2007/10/21 QQ:9073204 深圳

#003 void CreateFileDemo(void)

#004 {

#005 //

#006 HANDLE hFile = ::CreateFile(_T("CreateFileDemo.txt"), //創建文件的名稱。

#007 GENERIC_WRITE|GENERIC_READ, // 寫和讀文件。

#008 0, // 不共享讀寫。

#009 NULL, // 缺省安全屬性。

#010 CREATE_ALWAYS, // 如果文件存在,也創建。

#011 FILE_ATTRIBUTE_NORMAL, // 一般的文件。

#012 NULL); // 模板文件為空。

#013

#014 if (hFile == INVALID_HANDLE_VALUE)

#015 {

#016 //

#017 OutputDebugString(_T("CreateFile fail!/r/n"));

#018 }

#019

#020 //往文件裡寫數據。

#021 const int BUFSIZE = 4096;

#022 char chBuffer[BUFSIZE];

#023 memcpy(chBuffer,"Test",4);

#024 DWORD dwWritenSize = 0;

#025 BOOL bRet = ::WriteFile(hFile,chBuffer,4,&dwWritenSize,NULL);

#026 if (bRet)

#027 {

#028 //

#029 OutputDebugString(_T("WriteFile 寫文件成功/r/n"));

#030 }

#031

#032 //先把寫文件緩衝區的數據強制寫入磁盤。

#033 FlushFileBuffers(hFile);

#034

#035 //

#036 //從文件裡讀取數據。

#037 LONG lDistance = 0;

#038 DWORD dwPtr = SetFilePointer(hFile, lDistance, NULL, FILE_BEGIN);

#039 if (dwPtr == INVALID_SET_FILE_POINTER)

#040 {

#041 //獲取出錯碼。

#042 DWORD dwError = GetLastError() ;

#043 //處理出錯。

#044 }

#045

#046 DWORD dwReadSize = 0;

#047 bRet = ::ReadFile(hFile,chBuffer,4,&dwReadSize,NULL);

#048 if (bRet)

#049 {

#050 //

#051 OutputDebugString(_T("ReadFile 讀文件成功/r/n"));

#052 }

#053 else

#054 {

#055 //獲取出錯碼。

#056 DWORD dwError = GetLastError();

#057 //處理出錯。

#058 TCHAR chErrorBuf[1024];

#059 wsprintf(chErrorBuf,_T("GetLastError()=%d/r/n"),dwError);

#060 OutputDebugString(chErrorBuf);

#061 }

#062

#063 }