1. 程式人生 > >VC中怎麼讀取檔案

VC中怎麼讀取檔案

在VC中檔案操作有三種方式,使用C標準庫,使用WINAPI或使用MFC庫
一.C標準庫
1.建立開啟檔案fopen
FILE *fopen(const char* filename,
Const char* mode)//相應有Unicode版本 _wfopen
filename檔名
還有基於CRT的安全版本
errno_t fopen_s(
FILE ** pFile,
const char * filename,
const char * mode) //相應有Unicode版本 _wfopen_s
pFile要接收指向已開啟的檔案的指標的指標
filename檔名
mode:
r 以只讀方式開啟檔案,該檔案必須存在;
r+ 以可讀寫方式開啟檔案,該檔案必須存在;

rb+ 讀寫開啟一個二進位制檔案,允許讀資料;
rw+ 讀寫開啟一個文字檔案,允許讀和寫;
w 開啟只寫檔案,若檔案存在則檔案長度清為0,即該檔案內容會消失。若檔案不存在則建立該檔案;
w+ 開啟可讀寫檔案,若檔案存在則檔案長度清為零,即該檔案內容會消失。若檔案不存在則建立該檔案;
a 以附加的方式開啟只寫檔案。若檔案不存在,則會建立該檔案,如果檔案存在,寫入的資料會被加到檔案尾,即檔案原先的內容會被保留(EOF符保留);
a+ 以附加方式開啟可讀寫的檔案。若檔案不存在,則會建立該檔案,如果檔案存在,寫入的資料會被加到檔案尾後,即檔案原先的內容會被保留(原來的EOF符不保留);
wb 只寫開啟或新建一個二進位制檔案;只允許寫資料;

wb+ 讀寫開啟或建立一個二進位制檔案,允許讀和寫;
ab+ 讀寫開啟一個二進位制檔案,允許讀或在檔案末追加資料;
at+ 開啟一個叫string的檔案,a表示append,就是說寫入處理的時候是接著原來檔案已有內容寫入,不是從頭寫入覆蓋掉,t表示開啟檔案的型別是文字檔案,+號表示對檔案既可以讀也可以寫;
2.讀取檔案
size_t fread(void * buffer,
size_t size,
size_t count,
FILE * stream)
buffe輸出檔案的快取指標
size每次讀取的最小單位
count讀取次數
stream讀取的檔案指標
返回實際讀取到的檔案塊數
size_t fread_s(
void * buffer,

size_t bufferSize,
size_t elementSize,
size_t count,
FILE * stream)
buffer讀取資料的存取位置
bufferSize讀取資料的緩衝區大小
elementSize每次讀取塊的最小單位
count讀取想的數量
stream檔案控制代碼
3.fwrite寫操作
size_t fwrite(
const void * buffer,
size_t size,
size_t count,
FILE * stream)

4.fseek跳轉
int fseek(
FILE * stream,
Long offset,
int origin)//64位的跳轉方法fseeki64
offset偏移位置
origin初始位置 //三個引數SEEK_CUR檔案指標的當前位置;SEEK_END檔案結尾;SEEK_SET檔案開頭
成功返回0失敗非0值
5.關閉流fclose
Int fclose(FILE * stream)
如果關閉成功返回0
二.WinApi
1.建立或開啟一個檔案CreateFile
HANDLE CreateFile(LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
lpFileName要開啟的檔名稱
dwDesiredAccess指明物件的控制模式。一個應用可以包含讀控制,寫控制,讀/寫控制,裝置查詢控制;
0 指定裝置查詢控制:程式可以不訪問裝置就查詢到裝置屬性
GENERIC_READ 指定讀控制,可以從物件中讀取資料
GENERIC_WRITE 指定寫控制,可以向物件中寫資料
標準控制權限(16-23位掩碼):
DELETE 刪除物件的許可權。
READ_CONTROL 從物件的安全描述符中讀取資訊的許可權,但不包括SACL(系統訪問控制列表)中的資訊
WRITE_DAC 修改物件安全描述符中的DACL(隨機訪問控制列表)的許可權
WRITE_OWNER 修改物件安全描述符中的屬主的許可權
SYNCHRONIZE 同步化使用物件的許可權,即可以建立一個執行緒等待訊號量釋放(但有些物件不支援這個許可權)
STANDARD_RIGHTS_REQUIRED 等價於前面四種許可權的總合(通常這四種是必須具有的許可權)
STANDARD_RIGHTS_READ 一般等價於READ_CONTROL
STANDARD_RIGHTS_WRITE 一般等價於READ_CONTROL
STANDARD_RIGHTS_EXECUTE 一般等價於READ_CONTROL
STANDARD_RIGHTS_ALL 等價於前面五種許可權的總合
特殊控制權限(0-15位掩碼):
SPECIFIC_RIGHTS_ALL
ACCESS_SYSTEM_SECURITY
MAXIMUM_ALLOWED
GENERIC_READ
GENERIC_WRITE
GENERIC_EXECUTE
GENERIC_ALL
dwShareMode指定物件的共享模式,如果為0,表示是互斥使用的,如果CreateFile開啟成功,則別的程式只能等到當前程式關閉物件控制代碼CloseHandle後才能再開啟使用
FILE_SHARE_DELETE 開啟操作只有在刪除時才能返回成功
FILE_SHARE_READ 開啟操作只有在讀時才能返回成功
FILE_SHARE_WRITE 開啟操作只有在寫時才能返回成功
dwCreationDisposition指名當代開物件不存在時需要怎麼樣的處理,以下其中之一:
CREATE_NEW 建立新檔案/物件(當物件已經存在是將返回失敗)。
CREATE_ALWAYS 總是建立(如果物件存在就覆蓋它,清除當前屬性,把檔案屬性和dwFlagsAndAttributes指定的標誌相結合)。
OPEN_EXISTING 開啟檔案(如果不存在就返回失敗)。
OPEN_ALWAYS 存在就開啟;若不存在,假如dwCreationDisposition==CREATE_NEW就建立一個新檔案。
TRUNCATE_EXISTING 存在就開啟,且清空檔案內容(至少要有GENERIC_WRITE許可權);若檔案不存在就返回失敗。
dwFlagsAndAttribute指定檔案的屬性標誌以下任意組合,(有FILE_ATTRIBUTE_NORMAL必須單獨使用)
FILE_ATTRIBUTE_ARCHIVE檔案存檔(備份或移動時會對檔案做標記);FILE_ATTRIBUTE_ENCRYPTED 加密(對檔案來說是內容加密,對目錄來說是對將來新建的檔案預設為加密屬性),與此同時,如果還設定了FILE_ATTRIBUTE_SYSTEM屬性,當前這個屬性將無效;
FILE_ATTRIBUTE_HIDDEN 隱藏屬性;
FLE_ATTRIBUTE_NORMAL 檔案沒有其他屬性設定,此屬性只能單獨使用才合法;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 不建立內容索引;
FILE_ATTRIBUTE_OFFLINE 離線屬性。檔案內容暫時不可用。此屬性被Remote Storage軟體所用,不能任意更改;
FILE_ATTRIBUTE_READONLY 只讀檔案屬性。應用程式不能寫或刪除;
FILE_ATTRIBUTE_SYSTEM 檔案是系統檔案或被作業系統互斥地使用;
FILE_ATTRIBUTE_TEMPORARY 臨時檔案,使用過程中儘量留在記憶體以保證存取速度;
FILE_FLAG_WRITE_THROUGH 指示系統立即寫磁碟。這個寫操作允許被cache快取,但不能被擱置;
FILE_FLAG_OVERLAPPED 指示系統初始化物件,如果操作需要大量時間執行就先返回一 個 ERROR_IO_PENDING,當操作 完成後再通過事件使能訊號量。指定這個標誌就必須在read和write函式裡初始化OVERLAPPED 結構體,應用程式必須執行重複的讀寫操作。此時,作業系統不維護檔案指標,當前的位置 需要通過OVERLAPPED的指標傳遞給讀寫函式。這個標誌還允許多個操作的並行(並行讀寫);
FILE_FLAG_NO_BUFFERING 指示系統不要緩衝,它如果和FILE_FLAG_OVERLAPPED聯合使用,將呈現最好的非同步效能,因為I/O操作並不依賴於記憶體管理器的同步性。但是有時I/O操作會慢些,因為沒用cache。有時程式需要做調整,比如檔案大小必須是扇區大小的整數倍,Buffer地址的按扇區地址對齊等。按扇區地址對齊記憶體邊界可以使用VirtualAlloc來分配記憶體,GerDiskFreeSpace函式可以得到磁碟一個扇區的大小;
FILE_FLAG_RANDOM_ACCESS 指示檔案進行隨即存取,系統可據此對cache的分配進行優化;
FILE_FLAG_SEQUENTIAL_SCAN 指示順序存取,系統也可據此對cache的分配進行優化。即使有隨即存取的操作,也不會出錯,不過cache的優化就取消了。在連續讀取大檔案時效能非常好;
FILE_FLAG_DELETE_ON_CLOSE 指示系統在控制代碼關閉時將響應的檔案立即刪除,對當前控制代碼以外的其他控制代碼也有效。而且隨後的開啟請求也會失敗,直到你使用了FILE_SHARE_DELETE屬性;
FILE_FLAG_BACKUP_SEMANTICS 在Windows NT/2000/XP平臺上:指示檔案作為備份或恢復檔案開啟,這是如果呼叫程序擁有特殊許可權(SE_BACKUP_NAME 或 SE_RESTORE_NAME),就可以不進行安全檢查。也可以在獲得一個目錄的控制代碼時設定這個flag,目錄控制代碼可以代替檔案控制代碼傳遞給一些函式;
FILE_FLAG_POSIX_SEMANTICS 指明按照作業系統介面規範進行檔案存取,這包括允許多檔名的使用。請謹慎使用,因為MS_DOS或16位Windows系統可能不支援;
FILE_FLAG_OPEN_REPARSE_POINT 這個標誌指明禁止檔案系統的重解析點的動作。檔案開啟時就返回檔案的控制代碼,而不在乎控制重解析點的過濾器是否可執行。不能和CREATE_ALWAYS同時使用;
FILE_FLAG_OPEN_NO_RECALL 表明檔案資料被請求,但仍然駐留在遠端儲存體中,而不會被傳回本地儲存體。這個標誌 由遠端儲存系統或分層儲存管理系統使用。如果CreateFile函式開啟一個命名管道的客戶端,dwFlagsAndAttributes 引數也會包含服務資訊的安全性。當呼叫程式指定了;
SECURITY_PRESENT標誌時,dwFlagsAndAttributes 引數可以取以下一個或多個值: SECURITY_ANONYMOUS 指定將客戶端模擬在匿名級別(the Anonymous impersonation level)
SECURITY_IDENTIFICATION 指定將客戶端模擬在身份認證級別(the Identification impersonation level)
SECURITY_IMPERSONATION 指定將客戶端模擬在偽裝級別(the Impersonation impersonation level)
SECURITY_DELEGATION 指定將客戶端模擬在授權級別(the Delegation impersonation level)
SECURITY_CONTEXT_TRACKING 指定安全跟蹤模式是動態的,否則(不指定此標誌)是靜態的
SECURITY_EFFECTIVE_ONLY 指定客戶端的安全內容中的有效內容才可以被服務端使用,否則所有內容都可被使用。 這個標誌允許客戶端限制服務端在模擬客戶端時所具有的許可權。
hTemplateFile把具有GENERIC_READ許可權的控制代碼指定為一個模板檔案。這個模板檔案提供了檔案屬性和擴充套件屬性,用於建立檔案。在Windows95/98/Me平臺上:這個引數必須為空,否則如果你提供一個控制代碼,函式呼叫將會失敗,用GerLastError函式獲得的出錯資訊為ERROR_NOT_SUPPORTED
呼叫如果成功,返回值時一個開啟檔案的控制代碼。
在Windows 2000/XP平臺上:
如果你企圖開啟一個遠端機器上的檔案或目錄,dwDesiredAccess設定為DELETE或者任一其他的控制標誌,而這時遠端檔案或目錄還沒有以FILE_SHARE_DELETE的方式開啟的話,你的函式呼叫就會發生共享錯誤了。為了避免共享錯誤,一種辦法是單獨用DELETE方式開啟遠端檔案或目錄,另一種方法是在開啟檔案或目錄之前先呼叫DeleteFile函式。
如果dwCreationDisposition 引數指定為CREATE_ALWAYS 並且dwFlagsAndAttributes 引數指定為FILE_ATTRIBUTE_NORMAL 的話,CreateFile呼叫將失敗,GetLastError報告的錯誤是ACCESS_DENIED。這時,把dwFlagsAndAttributes 引數設定為FILE_ATTRIBUTE_HIDDEN和FILE_ATTRIBUTE_NORMAL的聯合值,將避免這個問題。
2.ReadFile函式從檔案指標指定的位置讀取資料。讀操作完成後,檔案指標將根據實際讀出的資料自動進行調整,除非檔案控制代碼是以OVERLAPPED屬性值開啟的。如果是以OVERLAPPED開啟的I/O,應用程式就需要自己手動調整檔案指標。
這個函式被設計成兼有同步和非同步操作。ReadFileEx函式則設計成只支援非同步操作,非同步操作允許應用程式在讀檔案期間可以同時進行其他的操作。
BOOL ReadFile(HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped)
hFile檔案控制代碼(必須具有GENERIC_READ訪問許可權)。在Windows NT/2000/XP平臺上:對於非同步讀操作,hFile可以是由CreateFile函式以FILE_FLAG_OVERLAPPED方式開啟的任何控制代碼,或者一個由socket或accept函式返回的socket控制代碼。 在Windows 95/98/Me平臺上:對於郵槽、命名管道和磁碟檔案不能使用非同步讀操作。
lpBuffer用來接收從檔案中讀出的資料的緩衝區指標。
nNumberOfBytesToRead 指明要讀的位元組總數。
lpNumberOfBytesRead 一個變數指標,用來儲存實際傳輸的位元組總數。ReadFile在做所有事情(包括錯誤檢查)之前,先將這個值賦為0。當ReadFile從一個命名管道上返回TRUE時這個引數為0,說明訊息管道另一端呼叫WriteFile時設定的nNumberOfBytesToWrite 引數為0;在Windows NT/2000/XP平臺上:如果lpOverlapped 為NULL,則lpNumberOfBytesRead不能為NULL。如果lpOverlapped 不是NULL,lpNumberOfBytesRead可以設為NULL。如果是一個overlapped形式的讀操作,我們可以動用GetOverlappedResult函式來獲得傳輸的實際位元組數。如果hFile關聯的是一個完成埠(I/O completion port),那麼可以呼叫GetQueuedCompletionStatus函式來獲得傳輸的實際位元組數。如果完成埠(I/O completion port)被佔用,而你用的是一個用於釋放記憶體的回撥例程,對於lpOverlapped引數指向的OVERLAPPED結構體來說,為這個引數指定NULL可以避免重新分配記憶體時發生記憶體洩漏。記憶體洩漏會導致返回這個引數值時是一個非法值。 Windows 95/98/Me平臺上:這個引數不允許為NULL。
lpOverlapped 一個指向OVERLAPPED結構體的指標。如果hFile是以FILE_FLAG_OVERLAPPED方式獲得的控制代碼,這個結構是必須的,不能為NULL。(否則函式會在錯誤的時刻報告讀操作已經完成了)。這時,讀操作在由OVERLAPPED中Offset成員指定的偏移地址開始讀,並且在實際完成讀操作之前就返回了。在這種情況下,ReadFile返回FALSE,GerLastError報告從錯誤型別是ERROR_IO_PENDING。這允許呼叫程序繼續其他工作直到讀操作完成。OVERLAPPED結構中的事件將會在讀操作完成時被使能。 如果hFile不是以FILE_FLAG_OVERLAPPED方式獲得的控制代碼,並且lpOverlapped為NULL,讀操作就從當前檔案的開始位置讀起,直到讀操作完成ReadFile函式才能返回。在Windows NT/2000/XP平臺上:如果hFile不是以FILE_FLAG_OVERLAPPED方式獲得的控制代碼,並且lpOverlapped不為NULL,則讀操作在由OVERLAPPED中Offset成員指定的偏移地址開始讀,直到讀操作完成ReadFile函式才能返回。在Windows 95/98/Me平臺上:對於檔案、磁碟、管道和郵槽的操作,這個引數必須為NULL。一個不為空的OVERLAPPED結構體指標將導致呼叫失敗。Windows 95/98/Me平臺只支援序列口和並行口的overlapped 讀寫。
有如下任一種情況發生都會導致函式返回:(1)在管道另一端的寫操作完成後(2)請求的位元組數傳輸完畢(3)發生錯誤。 如果函式正確,返回非零。 如果返回值是非零,但接收的位元組數是0,那麼可能是檔案指標在讀操作期間超出了檔案的end位置。然而,如果檔案以FILE_FLAG_OVERLAPPED方式開啟,lpOverlapped 引數不為NULL,檔案指標在讀操作期間超出了檔案的end位置,那麼返回值肯定是FALSE,GetLastError返回的錯誤是ERROR_HANDLE_EOF。
3.WriteFile可以以同步或非同步的方式向一個物件控制代碼中寫資料
BOOL WriteFile(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped)
三MFC
CFile類:通常,在CFile類構造時用於自動開啟一個磁碟檔案,析構時關閉檔案。靜態成員函式允許查閱一個未開啟的檔案。
1.Open開啟檔案
virtual BOOL Open(LPCTSTR lpszFileName,
UINT nOpenFlags,
CFileException* pError = NULL)
CFile::modeCreate 直接構造去建立一個新的檔案如果這個檔案存在,則刪除這個檔案裡所有內容   
CFile::modeNoTruncate 聯合建立屬性,如果這個檔案已建立,則不刪除原檔案內容,因而這個檔案是可以當做一個已經存在,或者不存在而被新建的檔案來保證開啟。這是非常有意義的,例如,開啟來設定一個存在或者不存在的檔案都是可以的。這個屬性對於CStdioFile也是非常好的
CFile::modeRead 開啟為只讀屬性.
CFile::modeWrite 開啟為只寫屬性.
CFile::modeReadWrite 開啟為讀寫屬性.
CFile::modeNoInherit 防止這個檔案來源於子程序.
CFile::shareDenyNone 在這個檔案讀寫處理之外開啟這個檔案
CFile::shareDenyRead 以獨佔方式開啟,拒絕其他讀操作
CFile::shareDenyWrite 以獨佔方式開啟,拒絕其他寫操作
CFile::shareExclusive 以獨佔方式開啟檔案,拒絕其他讀寫操作訪問這個檔案Opens the file with exclusive mode, denying other 如果這個檔案已開啟進行讀寫操作則構造失敗
CFile::shareCompat 這個屬性在 32 bit MFC是不可用的. This flag maps to CFile::shareExclusive 當應用在CFile::Open.
CFile::typeText 設定文字模式特別處理回車換行 (used in derived classes only).
CFile::typeBinary 設定二進位制模式(used in derived classes only).
2.讀檔案
virtual UINT Read(
void* lpBuf,
UINT nCount )
lpBuf:使用者指定的要儲存所讀的內容的緩衝區指標
nCount:指定要讀寫的最大位元組數
返回實際讀的位元組數 當遇到EOF時,小於nCount
3.寫檔案
virtual void Write(
const void* lpBuf,
UINT nCount)
lPBuf:指向要寫入的資料的緩衝區
nCount:要寫入的位元組數
4.重新整理快取
virtual void Flush( )
將檔案緩衝區中的資料寫進檔案中,一般在呼叫write函式之後都要呼叫以下Flush函式