天天看點

Windows API一日一練(56)SetEndOfFile和GetFileSizeEx函數

有一天,我正在開發BT軟體,它有這樣的一個功能,就是先把檔案的大小配置設定好,然後再慢慢地往裡面對應的位置寫入相應的資料。這樣的好處,就是可以先把磁盤空間占用起來,以便後面的下載下傳順利進行。要實作這個功能,就需要建立一個空的檔案,然後把檔案指針設定到相應大小的位置,然後再調用函數SetEndOfFile來設定檔案的結束位置,這樣檔案就有相應的大小了。在BT軟體的開發裡,也發現目錄的處理時需要詳細地記錄目錄裡的檔案大小,這就需要使用GetFileSizeEx函數來擷取檔案的大小。由于BT裡的視訊檔案比較大,有可能幾G的,一定要使用GetFileSizeEx函數來處理,這樣就可以擷取比較大的檔案而不出錯。

函數FlushFileBuffers和SetFilePointer聲明如下:

WINBASEAPI

BOOL

WINAPI

SetEndOfFile(

    __in HANDLE hFile

    );

GetFileSizeEx(

    __in HANDLE hFile,

    __out PLARGE_INTEGER lpFileSize

hFile是檔案句柄。

lpFileSize是擷取檔案傳回的大小。

調用函數的例子如下:

#001  //建立、寫入、讀取檔案。

#002  //蔡軍生 2007/10/23 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         //

#064         //

#065         //移動檔案指針到新的位置。

#066         lDistance = 3;

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

#068 

#069        //設定檔案新的結束位置。

#070        ::SetEndOfFile(hFile);

#071 

#072         //擷取檔案的大小。

#073        LARGE_INTEGER liFileSize;

#074        ::GetFileSizeEx(hFile,&liFileSize);

#075 

#076         TCHAR chTemp[128];

#077         wsprintf(chTemp,_T("GetFileSizeEx()=%d\r\n"),liFileSize);

#078         OutputDebugString(chTemp);

#079  

#080 

#081         //關閉檔案。

#082         if (hFile != INVALID_HANDLE_VALUE)

#083         {

#084               //

#085               CloseHandle(hFile);

#086         }

#087 

#088  }