您現在的位置: 365建站網 > 365學習 > C/C++ 文件操作之CreateFile函數、ReadFile函數和WriteFile函數的用法

C/C++ 文件操作之CreateFile函數、ReadFile函數和WriteFile函數的用法

文章來源:365jz.com     點擊數:3585    更新時間:2018-10-27 10:59   參與評論

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
);

參數列表:

參數類型描述
lpFileNameString ,要打開的文件的名字
dwDesiredAccessLong ,如果為 GENERIC_READ 表示允許對設備進行讀訪問;如果為 GENERIC_WRITE 表示允許對設備進行寫訪問(可組合使用);如果為零,表示只允許獲取與一個設備有關的信息
dwShareModeLong ,零表示不共享; FILE_SHARE_READ 和 / 或 FILE_SHARE_WRITE 表示允許對文件進行共享訪問
lpSecurityAttributesSECURITY_ATTRIBUTES ,指向一個 SECURITY_ATTRIBUTES 結構的指針,定義了文件的安全特性(如果操作系統支持的話)
dwCreationDispositionLong ,下述常數之一:CREATE_NEW 創建文件; 如文件存在則會出錯CREATE_ALWAYS 創建文件,會改寫前一個文件;OPEN_EXISTING 文件必須已經存在。由設備提出要求;OPEN_ALWAYS 如文件不存在則創建它;    TRUNCATE_EXISTING 將現有文件縮短為零長度
dwFlagsAndAttributesLong ,一個或多個下述常數: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 關閉了上一次打開的句柄后,將文件刪除。特別適合臨時文件;
hTemplateFileLong ,如果不為零,則指定一個文件句柄。新文件將從這個文件中復制擴展屬性

參數:

lpFileName [in]

    要創建或打開的文件或設備的名稱。 可以在這個名字中使用正斜杠(/)或反斜杠(\)【注意/是轉義符號】。在該函數的ANSI版本中,該名稱僅限于MAX_PATH字符。要將此限制擴展為32,767個寬字符,請調用該函數的Unicode版本并將“\\?\”添加到路徑中。更多內容請查看:Naming Files, Paths, and Namespaces.
    有關特殊設備名稱的信息,請參閱:Defining an MS-DOS Device Name.
    要創建文件流,請指定文件的名稱,冒號,然后指定流的名稱。 有關更多信息,請參閱File Streams.
    提示:從Windows 10版本1607開始,針對此函數的unicode版本(CreateFileW),您可以選擇刪除MAX_PATH限制而不預先添加“\\?\”。有關詳細信息,請參閱命名文件,路徑和命名空間的“Naming Files, Paths, and Namespaces ”部分。
dwDesiredAccess [in]
    所請求的文件或設備訪問權限,這可以被概括為讀,寫,兩者或非)。最常用的值是GENERIC_READ,GENERIC_WRITE或兩者(GENERIC_READ | GENERIC_WRITE)。更多內容查看;Generic Access Rights, File Security and Access Rights, File Access Rights Constants, and ACCESS_MASK.
    如果此參數為零,則應用程序可以查詢某些元數據(如文件,目錄或設備屬性),而不訪問該文件或設備,即使GENERIC_READ訪問已被拒絕。
    您無法請求與已打開句柄的打開請求中的dwShareMode參數指定的共享模式沖突的訪問模式。
    有關更多信息,請參閱本主題的“備注”部分和Creating and Opening Files.
dwShareMode [in]
    文件或設備的請求共享模式,可以讀取,寫入,刪除,全部或全部刪除。對屬性或擴展屬性的訪問請求不受此標志的影響。
    如果此參數為零且CreateFile成功,則文件或設備無法共享,并且無法再次打開,直到文件或設備的句柄關閉。
    你無法請求與在具有打開句柄的現有請求中指定的訪問模式沖突的共享模式。 CreateFile將失敗,GetLastError函數將返回ERROR_SHARING_VIOLATION。
    要啟用進程在另一進程打開文件或設備時共享文件或設備,請使用以下一個或多個值的兼容組合。有關此參數與dwDesiredAccess參數的有效組合的更多信息,請查看Creating and Opening Files.
提示:每個打開的句柄的共享選項在該句柄關閉之前保持有效,而與流程上下文無關。

ValueMeaning
0x00000000 防止其他進程在請求刪除,讀取或寫入訪問時打開文件或設備。

FILE_SHARE_DELETE                               

0x00000004

啟用文件或設備共享刪除訪問,否則,如果其他進程請求刪除訪問,則無法打開該文件或設備。如果未指定此標志,但文件或設備已被打開以進行刪除訪問,則該功能失敗。

注意:除訪問權限允許刪除和重命名操作

FILE_SHARE_READ

0x00000001

啟用文件或設備共享讀訪問,否則,如果其他進程請求讀取訪問權限,則無法打開文件或設備。如果未指定此標志,但文件或設備已被打開以進行讀取訪問,則該功能失敗。

FILE_SHARE_WRITE

0x00000002

啟用文件或設備共享寫訪問,否則,如果其他進程請求寫訪問權限,則無法打開該文件或設備。如果未指定此標志,但文件或設備已打開以進行寫入訪問或具有寫入訪問的文件映射,則該功能將失敗。

lpSecurityAttributes [in, optional]
    指向SECURITY_ATTRIBUTES結構的指針,該結構包含兩個獨立但相關的數據成員:一個可選的安全描述符以及一個布爾值,該值確定返回的句柄是否可以被子進程繼承。
    該參數可以是NULL。
    如果此參數為NULL,則由CreateFile返回的句柄不能由應用程序可能創建的任何子進程繼承,并且與返回句柄關聯的文件或設備將獲得默認安全描述符。
    該結構的lpSecurityDescriptor成員為文件或設備指定SECURITY_DESCRIPTOR。如果此成員為NULL,則與返回句柄關聯的文件或設備將被分配一個默認安全描述符。
    CreateFile在打開現有文件或設備時會忽略lpSecurityDescriptor成員,但會繼續使用bInheritHandle成員。
    該結構的bInheritHandle成員指定是否可以繼承返回的句柄。
dwCreationDisposition [in]
    采取存在或不存在的文件或設備的操作。
    對于文件以外的設備,此參數通常設置為OPEN_EXISTING。

    該參數必須是以下值之一,不能組合:

ValueMeaning

CREATE_ALWAYS

2

始終創建一個新文件。

如果指定的文件存在并且是可寫的,則該函數覆蓋文件,函數成功,并且最后的錯誤代碼被設置為ERROR_ALREADY_EXISTS(183)。

如果指定的文件不存在并且是有效的路徑,則會創建一個新文件,該函數成功,并且最后一個錯誤代碼被設置為零。

CREATE_NEW

1

只有在不存在的情況下才創建一個新文件。
如果指定的文件存在,則該函數失敗,并且最后的錯誤代碼被設置為ERROR_FILE_EXISTS(80)。
如果指定的文件不存在并且是可寫位置的有效路徑,則會創建一個新文件。
OPEN_ALWAYS
4
總是打開一個文件。
如果指定的文件存在,則函數成功并且最后的錯誤代碼被設置為ERROR_ALREADY_EXISTS(183)。
如果指定的文件不存在并且是可寫位置的有效路徑,則該函數將創建一個文件,并將最后一個錯誤代碼設置為零。
OPEN_EXISTING
3
只有存在文件或設備時才打開。
如果指定的文件或設備不存在,則該函數將失敗,并且最后一個錯誤代碼將設置為ERROR_FILE_NOT_FOUND(2)。
TRUNCATE_EXISTING           
5
打開一個文件并截斷它,以便它的大小為零字節,只要它存在。
如果指定的文件不存在,則該函數失敗,并且最后的錯誤代碼被設置為ERROR_FILE_NOT_FOUND(2)。
調用進程必須打開GENERIC_WRITE位設置為dwDesiredAccess參數的一部分的文件。

dwFlagsAndAttributes [in]
    文件或設備屬性和標志FILE_ATTRIBUTE_NORMAL是文件最常用的默認值。
   此參數可以包含可用文件屬性的任意組合(FILE_ATTRIBUTE_ *)。 所有其他文件屬性都會覆蓋FILE_ATTRIBUTE_NORMAL。
    此參數還可以包含用于控制文件或設備緩存行為,訪問模式和其他特殊用途標志的標志組合(FILE_FLAG_ *)。 這些與任何FILE_ATTRIBUTE_ *值結合使用。
    此參數還可以通過指定SECURITY_SQOS_PRESENT標志來包含安全服務質量(SQOS)信息。
    當CreateFile打開現有文件時,它通常將文件標志與現有文件的文件屬性組合在一起,并忽略作為dwFlagsAndAttributes的一部分提供的任何文件屬性。
    官方文檔中還有列出很多文件和設備屬性和標志的表格,內容太多不再列出,建議參考原文。
hTemplateFile [in, optional]
    具有GENERIC_READ訪問權限的模板文件的有效句柄。模板文件為正在創建的文件提供文件屬性和擴展屬性。
    該參數可以是NULL。
    打開現有文件時,CreateFile將忽略此參數。

    打開新的加密文件時,該文件從其父目錄繼承自主訪問控制列表。


返回值:
    如果函數成功,則返回值是指定文件,設備,命名管道或郵件插槽的打開句柄。

    如果該函數失敗,則返回值為INVALID_HANDLE_VALUE。 要獲得擴展的錯誤信息,請調用GetLastError。

備注:

    CreateFile最初是專門為文件交互而開發的,但后來被擴展和增強,以包括Windows開發人員可用的大多數其他類型的I / O設備和機制。本節試圖涵蓋開發人員在不同上下文和不同I / O類型中使用CreateFile時可能遇到的各種問題

下面的代碼實現了在文件末尾寫入數據的過程:



#include <stdio.h>
#include <windows.h>
int main()
{
    HANDLE hFILE=CreateFile("1.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hFILE==INVALID_HANDLE_VALUE)
    {
        printf("CreateFile error\n");
        return 0;
    }
    if(SetFilePointer(hFILE,0,NULL,FILE_END)==-1)
    {
        printf("SetFilePointer error\n");
        return 0;
    }
    char buff[256]="hello";
    DWORD dwWrite;
    if(!WriteFile(hFILE,&buff,strlen(buff),&dwWrite,NULL))
    {
        printf("WriteFile error\n");
        return 0;
    }
    printf("write %d.\n",dwWrite);
    printf("done.\n");
    CloseHandle(hFILE);
    return 0;
}


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;
}


// CreateFile.cpp : 定義控制臺應用程序的入口點。
//此代碼將該CPP文件中的類容完整輸出在控制臺。也可以利用該函數進行拷貝文本文件,實際讀取字節要比定義的結構體小一字節,否則會沒有結束標志哦
#include "stdafx.h"
#include <windows.h>
#include "iostream"
using namespace std;
int main()
{
HANDLE hFile = CreateFile(TEXT("CreateFile.cpp"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
CHAR FileContext[256];
DWORD ReadInt = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "Open file failed! LastError is " << GetLastError() << endl;
}
while (ReadFile(hFile, FileContext,255,&ReadInt,NULL)>0 && ReadInt>0)
{
cout << FileContext << endl;
memset(FileContext,0,sizeof(FileContext));
}
   
system("Pause");
return 0;
}


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;
}


如對本文有疑問,請提交到交流論壇,廣大熱心網友會為你解答??! 點擊進入論壇


發表評論 (3585人查看,0條評論)
請自覺遵守互聯網相關的政策法規,嚴禁發布色情、暴力、反動的言論。
用戶名: 驗證碼: 點擊我更換圖片
最新評論
------分隔線----------------------------
自拍偷拍福力视频,偷拍国际精品,麻豆一区福利电影,国产网红视频午夜福利,se视频大全,久久国产AV影院 jessica jane中国女人| 少妇的滋味完整版| 特级欧美午夜aa片| 草莓视频app无限观看| 1001问夫妻性生活| 黄色动漫| 黄页网址大全免费安全| 免费看av大片的网站| 性欧美video高清| 少妇高潮惨叫久久久久电影| 在线观看无码h片| 乱伦色图| 成人免费午a大片| 日本免mv岛国片资源在线观看| 婷婷五月色综合| 强奷漂亮少妇高潮| 日本免费最新高清不卡视频| 老板你的太长太大了| 国产午夜福利片在线播放| 黑人30公分全部进入正在播放| 日本人真人爱视频全部过程| 人与动人物xxxxx| 免费乱理伦片在线观看2018| 无码中文人妻在线三区| 性xxxx欧美老妇胖老太肥肥| 国产在线精品一区二区三区| 好紧好湿好黄的视频| 国产小屁孩cao大人| 成年黄页网站大全免费无码| 欧美天堂av欧美日韩国产综合| 亲近乱子伦免费视频| http://www.syouei923.com