文件操作編程之文件讀寫

文件讀寫

微軟提供了強大的文件讀寫(文件I/O)操作的編程接口,我們可以通過調用API函數的方式來實現文件的讀寫。一般情況下,文件的讀寫過程如圖所示:

Created with Raphaël 2.1.0調用CreateFile函數打開或創建文件,返回文件句柄利用文件句柄調用WriteFile或者ReadFile函數寫入或讀取文件調用closeHandle函數關閉文件句柄

CreateFile函數

該函數的具體定義格式如下:

HANDLE CreateFile(
    LPCTSTR lpFileName,//指向文件名的指針
    DWORD dwDesiredAccess,//訪問模式(讀/寫)
    DWORD dwShareMode,//共享模式
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,//指向安全屬性的指針
    DWORD dwCreationDisposition,//如何創建
    DWORD dwFlagsAndAttributes,//文件屬性
    HANDLE hTemplateFile//用於複製文件句柄
    );

其中各個函數的具體要求如下:

  • lpFileName:要打開的文件名稱
  • dwDesiredAccess:如爲 GENERIC_READ 表示允許對設備進行讀訪問;如爲 GENERIC_WRITE 表示允許對設備進行寫操作(可組合使用);如爲0,表示只允許獲取與一個設備有關的信息。
  • dwShareMode : 該參數的作用是定義共享模式。其值爲0表示不共享;而爲FILE_SHARE_READ和/或FILE_SHARE_WRITE表示允許對文件進行共享訪問。
  • lpSecurityAttributes :指向一個SECURITY_ATTRIBUTES結構的指針,定義了文件的安全特性(如果系統支持)。
  • dwCreationDisposition : 指定當文件存在或不存在時的操作,常見的操作有如下5種:
    1. CREATE_NEW : 創建文件,如文件存在,則會出錯。
    2. CREATE_ALWAYS:創建文件,會改下前一個文件。
    3. OPEN_EXCITING : 文件必須已經存在,由設備提出要求。
    4. OPEN_ALWAYS : 如文件不存在,則創建它。
    5. TRUNCATE_EXCITING : 將現有文件的長度縮短爲零。
  • dwFlagsAndAttributes :表示新創建文件的屬性,文件常見的屬性有以下五種:
    1. FILE_ATTRIBUTE_ARCHIVE:表示歸檔屬性。
    2. FILE_ATTRIBUTE_NORMAL:默認屬性。
    3. FILE_ATTRIBUTE_HIDDEN : 隱藏文件或目錄。
    4. FILE_ATTRIBUTE_READONLY:文件爲只讀。
    5. FILE_ATTRIBUTE_SYSTEM:文件爲系統文件。
  • hTemplateFile:該參數指向用於存儲的文件句柄,如果不爲0,則指定一個文件句柄,新文件將從這個文件中複製擴展屬性。

如果該函數調用成功,則返回文件句柄。否則返回INVALID_HANDLE_VALUE。


WriteFile/ReadFile函數

在成功調用CreateFile創建文件句柄之後,就返回所打開或創建的文件的句柄,可調用WriteFile函數或者ReadFile函數來讀取文件。

這兩個文件的具體格式如下:

BOOL WriterFile(
    HANDLE hFile,//文件句柄
    LPCVOID lpBuffer,//數據緩衝區指針
    DWORD nNumberOfBytesToWrite,//要寫入的字節數
    LPDWORD lpNumberOfBytesWritten,//用於保存實際寫入字節數的存儲區域的指針
    LPOVERLAPPED lpOverlapped//結構體指針
    );

BOOL ReadFile(
    HANDLE hFile,//文件句柄
    LPCVOID lpBuffer,//數據緩衝區指針
    DWORD nNumberOfBytesToRead,//要讀取的字節數
    LPDWORD lpNumberOfBytesRead,//指向保存實際讀取字節數的存儲區域的指針
    LPOVERLAPPED lpOverlapped//結構體指針
    );

其中各個函數的具體要求如下:

  • hFile:該參數指向要讀寫的文件句柄,一般由CreateFile函數返回。
  • lpBuffer : 指向一個緩衝區,用於存儲讀寫的數據。
  • nNumberOfBytesToWrite/Read : 這兩個參數是表示要求寫入或讀取的字節數。
  • lpNumberOfBytesWritten/Read : 這兩個參數是表示返回實際寫入或讀取的字節數。
  • lpOverlapped :是指向OVERLAPPED結構的指針,設置爲NULL即可。

如果讀取或寫入操作成功,函數就會返回TRUE。在完成文件的讀寫操作後還需調用Handle函數關閉文件的句柄,以便其他程序對文件進行操作。


下面代碼演示瞭如何在文件末尾寫入數據,其具體過程如下:

#include <stdio.h>
#include <windows.h>
#include <iostream>

int main(int argc, char* argv[])
{
    //調用CreateFile函數以只寫方式打開一個文件
    HANDLE hFile = CreateFile(argv[1], GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile error\n");
        return 0;
    }
    //調用SetFilePointer函數調整文件指針位置,移動到文件末尾
    if (SetFilePointer(hFile, 0, NULL, FILE_END) == -1)
    {
        printf("SetFilePointer error\n");
        return 0;
    }
    char buff[256] = "配置信息";
    DWORD dwWrite;
    //把buff中的內容寫入到文件末尾
    if(!WriteFile(hFile, &buff, strlen(buff), &dwWrite, NULL))
    {
        printf("WriteFile Error\n");
        return 0;
    }
    printf("往 %s 中寫入數據成功\n",argv[1]);
    CloseHandle(hFile);
    return 0;
}

其中SetFilePointer函數的作用是設置文件指針的位置。當一個文件被打開時,系統會維護一個文件指針,指向文件的下一個讀寫操作的位置,所以隨着文件的讀寫,文件指針的位置也會隨之移動。

我想要更好更遠的月亮
想要未知的瘋狂
想要聲色的張揚

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章