C/C++ 檔案操作之CreateFile、ReadFile和WriteFile
阿新 • • 發佈:2019-02-07
1. CreateFile
這個函式的功能是建立或者開啟一個檔案或者I/O裝置,通常使用的I/O形式有檔案、檔案流、目錄、物理磁碟、卷、終端流等。如執行成功,則返回檔案控制代碼。 INVALID_HANDLE_VALUE 表示出錯,會設定 GetLastError 。
函式的宣告定義:
HANDLE WINAPI CreateFile(
_In_ LPCTSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);
引數列表:
引數 | 型別描述 |
---|---|
lpFileName | String ,要開啟的檔案的名字 |
dwDesiredAccess | Long ,如果為 GENERIC_READ 表示允許對裝置進行讀訪問;如果為 GENERIC_WRITE 表示允許對裝置進行寫訪問(可組合使用);如果為零,表示只允許獲取與一個裝置有關的資訊 |
dwShareMode | Long ,零表示不共享; FILE_SHARE_READ 和 / 或 FILE_SHARE_WRITE 表示允許對檔案進行共享訪問 |
lpSecurityAttributes | SECURITY_ATTRIBUTES ,指向一個 SECURITY_ATTRIBUTES 結構的指標,定義了檔案的安全特性(如果作業系統支援的話) |
dwCreationDisposition | Long ,下述常數之一:CREATE_NEW 建立檔案; 如檔案存在則會出錯CREATE_ALWAYS 建立檔案,會改寫前一個檔案;OPEN_EXISTING 檔案必須已經存在。由裝置提出要求;OPEN_ALWAYS 如檔案不存在則建立它; TRUNCATE_EXISTING 將現有檔案縮短為零長度 |
dwFlagsAndAttributes | Long ,一個或多個下述常數:FILE_ATTRIBUTE_ARCHIVE 標記歸檔屬性;FILE_ATTRIBUTE_COMPRESSED 將檔案標記為已壓縮,或者標記為檔案在目錄中的預設壓縮方式;FILE_ATTRIBUTE_NORMAL 預設屬性; FILE_ATTRIBUTE_HIDDEN 隱藏檔案或目錄;FILE_ATTRIBUTE_READONLY 檔案為只讀;FILE_ATTRIBUTE_SYSTEM 檔案為系統檔案;FILE_FLAG_WRITE_THROUGH 作業系統不得推遲對檔案的寫操作; FILE_FLAG_OVERLAPPED 允許對檔案進行重疊操作;FILE_FLAG_NO_BUFFERING 禁止對檔案進行緩衝處理。檔案只能寫入磁碟卷的扇區塊;FILE_FLAG_RANDOM_ACCESS 針對隨機訪問對檔案緩衝進行優化; FILE_FLAG_SEQUENTIAL_SCAN 針對連續訪問對檔案緩衝進行優化 ;FILE_FLAG_DELETE_ON_CLOSE 關閉了上一次開啟的控制代碼後,將檔案刪除。特別適合臨時檔案; |
hTemplateFile | Long ,如果不為零,則指定一個檔案控制代碼。新檔案將從這個檔案中複製擴充套件屬性 |
2. ReadFile
從檔案指標指向的位置開始將資料讀出到一個檔案中, 且支援同步和非同步操作,如果檔案開啟方式沒有指明FILE_FLAG_OVERLAPPED的話,當程式呼叫成功時,它將實際讀出檔案的位元組數儲存到lpNumberOfBytesRead指明的地址空間中。FILE_FLAG_OVERLAPPED 允許對檔案進行重疊操作。
函式宣告定義:
BOOL WINAPI ReadFile(
__in HANDLE hFile, // 檔案控制代碼
__out LPVOID lpBuffer, // 接收資料用的 buffer
__in DWORD nNumberOfBytesToRead, // 要讀取的位元組數
__out LPDWORD lpNumberOfBytesRead, // 實際讀取到的位元組數
__in LPOVERLAPPED lpOverlapped // OVERLAPPED 結構,一般設定為 NULL
);
程式碼示例:
BOOL Read(char *filePath)
{
HANDLE pFile;
DWORD fileSize;
char *buffer,*tmpBuf;
DWORD dwBytesRead,dwBytesToRead,tmpLen;
pFile = CreateFile(filePath,GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING, //開啟已存在的檔案
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( pFile == INVALID_HANDLE_VALUE)
{
printf("open file error!\n");
CloseHandle(pFile);
return FALSE;
}
fileSize = GetFileSize(pFile,NULL); //得到檔案的大小
buffer = (char *) malloc(fileSize);
ZeroMemory(buffer,fileSize);
dwBytesToRead = fileSize;
dwBytesRead = 0;
tmpBuf = buffer;
do{ //迴圈讀檔案,確保讀出完整的檔案
ReadFile(pFile,tmpBuf,dwBytesToRead,&dwBytesRead,NULL);
if (dwBytesRead == 0)
break;
dwBytesToRead -= dwBytesRead;
tmpBuf += dwBytesRead;
} while (dwBytesToRead > 0);
// TODO 處理讀到的資料 buffer
free(buffer);
CloseHandle(pFile);
return TRUE;
}
3. WriteFile
將資料寫入一個檔案。該函式比fwrite函式要靈活的多。也可將這個函式應用於對通訊裝置、管道、套接字以及郵槽的處理。返回時,TRUE(非零)表示成功,否則返回零。會設定GetLastError。
函式宣告定義:
BOOL WINAPI WriteFile(
__in HANDLE hFile, // 檔案控制代碼
__in LPCVOID lpBuffer, // 要寫入的資料
__in DWORD nNumberOfBytesToWrite, // 要寫入的位元組數
__out LPDWORD lpNumberOfBytesWritten, // 實際寫入的位元組數
__in LPOVERLAPPED lpOverlapped // OVERLAPPED 結構,一般設定為 NULL
);
程式碼示例:
BOOL Write(char *buffer, DWORD contentLen)
{
HANDLE pFile;
char *tmpBuf;
DWORD dwBytesWrite,dwBytesToWrite;
pFile = CreateFile(filePath,GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS, //總是建立檔案
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( pFile == INVALID_HANDLE_VALUE)
{
printf("create file error!\n");
CloseHandle(pFile);
return FALSE;
}
dwBytesToWrite = contentLen;
dwBytesWrite = 0;
tmpBuf = buffer;
do{ //迴圈寫檔案,確保完整的檔案被寫入
WriteFile(pFile,tmpBuf,dwBytesToWrite,&dwBytesWrite,NULL);
dwBytesToWrite -= dwBytesWrite;
tmpBuf += dwBytesWrite;
} while (dwBytesToWrite > 0);
CloseHandle(pFile);
return TRUE;
}