解讀VC++編程中的文件操作API和CFile類
在VC編程中,操作文件的方法主要有兩種:利用API函數(shù)和MFC的CFile類。微軟在其中封裝了文件的一般操作,下面我就介紹一下如何利用這兩
種方法實(shí)現(xiàn)文件操作。
1.創(chuàng)建或打開一個(gè)文件
API函數(shù)CreateFile可打開和創(chuàng)建文件、管道、郵槽、通信服務(wù)、設(shè)備以及控制臺,但是在此時(shí)只是介紹用這個(gè)函數(shù)怎么實(shí)現(xiàn)創(chuàng)建和打開一
個(gè)文件。
HANDLE CreateFile(
LPCTSTR lpFileName, // 要打開的文件名
DWORD dwDesiredAccess, // 文件的操作屬性
DWORD dwShareMode, // 文件共享屬性
LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 文件安全特性
DWORD dwCreationDisposition, //文件操作
DWORD dwFlagsAndAttributes, // 文件屬性
HANDLE hTemplateFile // 如果不為零,則指定一個(gè)文件句柄。新文件將從這個(gè)文件中復(fù)制擴(kuò)展屬性
);
文件的操作屬性:如果為零,表示只允許獲取與一個(gè)設(shè)備有關(guān)的信息,GENERIC_READ 表示允許對設(shè)備進(jìn)行讀訪問;如果為 GENERIC_WRITE
表示允許對設(shè)備進(jìn)行寫訪問(可組合使用);
文件的共享屬性:零表示不共享; FILE_SHARE_READ 或 FILE_SHARE_WRITE 表示允許對文件進(jìn)行讀/寫共享訪問;
文件的操作有:
·CREATE_NEW:創(chuàng)建文件;如文件存在則會出錯(cuò)
·CREATE_ALWAYS:創(chuàng)建文件,會改寫前一個(gè)文件
·OPEN_EXISTING:文件必須已經(jīng)存在。由設(shè)備提出要求
·OPEN_ALWAYS:如文件不存在則創(chuàng)建它
·TRUNCATE_EXISTING:將現(xiàn)有文件縮短為零長度
文件屬性有:
·FILE_ATTRIBUTE_ARCHIVE:標(biāo)記歸檔屬性
·FILE_ATTRIBUTE_COMPRESSED:將文件標(biāo)記為已壓縮,或者標(biāo)記為文件在目錄中的默認(rèn)壓縮方式
·FILE_ATTRIBUTE_NORMAL:默認(rèn)屬性
·FILE_ATTRIBUTE_HIDDEN:隱藏文件或目錄
·FILE_ATTRIBUTE_READONLY:文件為只讀
·FILE_ATTRIBUTE_SYSTEM:文件為系統(tǒng)文件
·FILE_FLAG_WRITE_THROUGH:操作系統(tǒng)不得推遲對文件的寫操作
·FILE_FLAG_OVERLAPPED:允許對文件進(jìn)行重疊操作
·FILE_FLAG_NO_BUFFERING:禁止對文件進(jìn)行緩沖處理。文件只能寫入磁盤卷的扇區(qū)塊
·FILE_FLAG_RANDOM_ACCESS:針對隨機(jī)訪問對文件緩沖進(jìn)行優(yōu)化
·FILE_FLAG_SEQUENTIAL_SCAN:針對連續(xù)訪問對文件緩沖進(jìn)行優(yōu)化
·FILE_FLAG_DELETE_ON_CLOSE:關(guān)閉了上一次打開的句柄后,將文件刪除。特別適合臨時(shí)文件
可以組合的屬性有:FILE_FLAG_WRITE_THROUGH,F(xiàn)ILE_FLAG_OVERLAPPED,F(xiàn)ILE_FLAG_NO_BUFFERING,F(xiàn)ILE_FLAG_RANDOM_ACCESS,
FILE_FLAG_SEQUENTIAL_SCAN,F(xiàn)ILE_FLAG_DELETE_ON_CLOSE,F(xiàn)ILE_FLAG_BACKUP_SEMANTICS,F(xiàn)ILE_FLAG_POSIX_SEMANTICS,
FILE_FLAG_OPEN_REPARSE_POINT,F(xiàn)ILE_FLAG_OPEN_NO_RECALL
如果成功返回一個(gè)打開文件得句柄,如果調(diào)用函數(shù)之前文件存在,文件操作屬性為:CREATE_ALWAYS 或 OPEN_ALWAYS,使用GetLastError
函數(shù)返回的是ERROR_ALREADY_EXISTS(包括函數(shù)操作成功),如果之前函數(shù)不存在,則返回0。使用失敗返回INVALID_HANDLE_VALUE,要取得更
多的信息,使用GetLastError函數(shù)。
文件關(guān)閉用:
BOOL CloseHandle(HANDLE hObject // handle to object to close);
例子1、在當(dāng)前目錄下面創(chuàng)建一個(gè)文件:
HANDLE handle;
DWORD Num;
handle= ::CreateFile("new.tmp",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
FILE_FLAG_DELETE_ON_CLOSE,NULL);
if(INVALID_HANDLE_VALUE!= handle )
{
::SetFilePointer(handle,0,0,FILE_BEGIN);
char Buffer[] = "這是個(gè)剛創(chuàng)建的文件";
::WriteFile(handle,Buffer,sizeof(Buffer),&Num,NULL);
ZeroMemory(Buffer,sizeof(Buffer));
::SetFilePointer(handle,0,0,FILE_BEGIN);
::ReadFile(handle,Buffer,sizeof(Buffer),&Num,NULL);
MessageBox(Buffer);
::CloseHandle(handle);
}
可以改變上面的創(chuàng)建文件的屬性和操作看下不同效果。
CFile創(chuàng)建和打開一個(gè)文件:
創(chuàng)建文件和打開文件的方法有很多種,下面簡單介紹下幾個(gè)構(gòu)造函數(shù):
CFile( LPCTSTR lpszFileName, UINT nOpenFlags );
throw( CFileException );
CFile( );
BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );
lpszFileName:文件名稱,可以是相對路徑,絕對路徑或網(wǎng)絡(luò)路徑
nOpenFlags:打開方式有:
·CFile::modeCreate 調(diào)用構(gòu)造函數(shù)構(gòu)造一個(gè)新文件,如果文件已存在,則長度變成0。
·CFile::modeNoTruncate 此值與modeCreate組合使用。如果所創(chuàng)建的文件已存在則其長度不變?yōu)?。因而此文件被打開,或者作為一個(gè)新 文件或者作為一個(gè)已存在的文件。這將是很有用的,例如當(dāng)打開一個(gè)可能存在也可能不存在的文件時(shí)。
·CFile::modeRead 打開文件僅供讀。
·CFile::modeReadWrite 打開文件供讀寫。
·CFile::modeWrite 打開文件僅供寫。
·CFile::modeNoInherit 阻止文件被子進(jìn)程繼承。
·CFile::ShareDenyNone 不禁止其它進(jìn)程讀或?qū)懺L問,打開文件。如果文件已被其它進(jìn)程以兼容模式打開,則Create失敗。
·CFile::ShareDenyRead 打開文件,禁止其它進(jìn)程讀此文件。如果文件已被其它進(jìn)程以兼容模式打開,或被其它進(jìn)程讀,則Create失敗。
·CFile::ShareDenyWrite 打開文件,禁止其它進(jìn)程寫此文件。如果文件已被其它進(jìn)程以兼容模式打開,或被其它進(jìn)程寫,則Create失敗
。
·CFile::ShareExclusive 以獨(dú)占模式打開文件,禁止其它進(jìn)程對文件的讀寫。如果文件已經(jīng)以淥J醬蚩列矗詞貢壞鼻敖蹋?
則構(gòu)造失敗。
·CFile::ShareCompat 此標(biāo)志在32位MFC中無效。此標(biāo)志在使用CFile:: Open時(shí)映射為CFile::ShareExclusive。
·CFile::typeText 對回車換行設(shè)置特殊進(jìn)程(僅用于派生類)。
·CFile::typeBinary 設(shè)置二進(jìn)制模式(僅用于派生類)。
下面給出MSDN中的一個(gè)例子:
char* pFileName = "test.dat";
TRY
{
CFile f( pFileName, CFile::modeCreate | CFile::modeWrite );
}
CATCH( CFileException, e )
{
#ifdef _DEBUG
afxDump << "File could not be opened " << e->m_cause << "\n";
#endif
}
END_CATCH
CFile fileTest;
char* pFileName = "test.dat";
TRY
{
fileTest.Open(pFileName, CFile::modeCreate |CFile::modeWrite);
}
CATCH_ALL(e)
{
fileTest.Abort( );
THROW_LAST ( );
}
END_CATCH_ALL
在VC編程中,操作文件的方法主要有兩種:利用API函數(shù)和MFC的CFile類。微軟在其中封裝了文件的一般操作,下面我就介紹一下如何利用這兩
種方法實(shí)現(xiàn)文件操作。
1.創(chuàng)建或打開一個(gè)文件
API函數(shù)CreateFile可打開和創(chuàng)建文件、管道、郵槽、通信服務(wù)、設(shè)備以及控制臺,但是在此時(shí)只是介紹用這個(gè)函數(shù)怎么實(shí)現(xiàn)創(chuàng)建和打開一
個(gè)文件。
HANDLE CreateFile(
LPCTSTR lpFileName, // 要打開的文件名
DWORD dwDesiredAccess, // 文件的操作屬性
DWORD dwShareMode, // 文件共享屬性
LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 文件安全特性
DWORD dwCreationDisposition, //文件操作
DWORD dwFlagsAndAttributes, // 文件屬性
HANDLE hTemplateFile // 如果不為零,則指定一個(gè)文件句柄。新文件將從這個(gè)文件中復(fù)制擴(kuò)展屬性
);
文件的操作屬性:如果為零,表示只允許獲取與一個(gè)設(shè)備有關(guān)的信息,GENERIC_READ 表示允許對設(shè)備進(jìn)行讀訪問;如果為 GENERIC_WRITE
表示允許對設(shè)備進(jìn)行寫訪問(可組合使用);
文件的共享屬性:零表示不共享; FILE_SHARE_READ 或 FILE_SHARE_WRITE 表示允許對文件進(jìn)行讀/寫共享訪問;
文件的操作有:
·CREATE_NEW:創(chuàng)建文件;如文件存在則會出錯(cuò)
·CREATE_ALWAYS:創(chuàng)建文件,會改寫前一個(gè)文件
·OPEN_EXISTING:文件必須已經(jīng)存在。由設(shè)備提出要求
·OPEN_ALWAYS:如文件不存在則創(chuàng)建它
·TRUNCATE_EXISTING:將現(xiàn)有文件縮短為零長度
文件屬性有:
·FILE_ATTRIBUTE_ARCHIVE:標(biāo)記歸檔屬性
·FILE_ATTRIBUTE_COMPRESSED:將文件標(biāo)記為已壓縮,或者標(biāo)記為文件在目錄中的默認(rèn)壓縮方式
·FILE_ATTRIBUTE_NORMAL:默認(rèn)屬性
·FILE_ATTRIBUTE_HIDDEN:隱藏文件或目錄
·FILE_ATTRIBUTE_READONLY:文件為只讀
·FILE_ATTRIBUTE_SYSTEM:文件為系統(tǒng)文件
·FILE_FLAG_WRITE_THROUGH:操作系統(tǒng)不得推遲對文件的寫操作
·FILE_FLAG_OVERLAPPED:允許對文件進(jìn)行重疊操作
·FILE_FLAG_NO_BUFFERING:禁止對文件進(jìn)行緩沖處理。文件只能寫入磁盤卷的扇區(qū)塊
·FILE_FLAG_RANDOM_ACCESS:針對隨機(jī)訪問對文件緩沖進(jìn)行優(yōu)化
·FILE_FLAG_SEQUENTIAL_SCAN:針對連續(xù)訪問對文件緩沖進(jìn)行優(yōu)化
·FILE_FLAG_DELETE_ON_CLOSE:關(guān)閉了上一次打開的句柄后,將文件刪除。特別適合臨時(shí)文件
可以組合的屬性有:FILE_FLAG_WRITE_THROUGH,F(xiàn)ILE_FLAG_OVERLAPPED,F(xiàn)ILE_FLAG_NO_BUFFERING,F(xiàn)ILE_FLAG_RANDOM_ACCESS,
FILE_FLAG_SEQUENTIAL_SCAN,F(xiàn)ILE_FLAG_DELETE_ON_CLOSE,F(xiàn)ILE_FLAG_BACKUP_SEMANTICS,F(xiàn)ILE_FLAG_POSIX_SEMANTICS,
FILE_FLAG_OPEN_REPARSE_POINT,F(xiàn)ILE_FLAG_OPEN_NO_RECALL
如果成功返回一個(gè)打開文件得句柄,如果調(diào)用函數(shù)之前文件存在,文件操作屬性為:CREATE_ALWAYS 或 OPEN_ALWAYS,使用GetLastError
函數(shù)返回的是ERROR_ALREADY_EXISTS(包括函數(shù)操作成功),如果之前函數(shù)不存在,則返回0。使用失敗返回INVALID_HANDLE_VALUE,要取得更
多的信息,使用GetLastError函數(shù)。
文件關(guān)閉用:
BOOL CloseHandle(HANDLE hObject // handle to object to close);
例子1、在當(dāng)前目錄下面創(chuàng)建一個(gè)文件:
HANDLE handle;
DWORD Num;
handle= ::CreateFile("new.tmp",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
FILE_FLAG_DELETE_ON_CLOSE,NULL);
if(INVALID_HANDLE_VALUE!= handle )
{
::SetFilePointer(handle,0,0,FILE_BEGIN);
char Buffer[] = "這是個(gè)剛創(chuàng)建的文件";
::WriteFile(handle,Buffer,sizeof(Buffer),&Num,NULL);
ZeroMemory(Buffer,sizeof(Buffer));
::SetFilePointer(handle,0,0,FILE_BEGIN);
::ReadFile(handle,Buffer,sizeof(Buffer),&Num,NULL);
MessageBox(Buffer);
::CloseHandle(handle);
}
可以改變上面的創(chuàng)建文件的屬性和操作看下不同效果。
CFile創(chuàng)建和打開一個(gè)文件:
創(chuàng)建文件和打開文件的方法有很多種,下面簡單介紹下幾個(gè)構(gòu)造函數(shù):
CFile( LPCTSTR lpszFileName, UINT nOpenFlags );
throw( CFileException );
CFile( );
BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );
lpszFileName:文件名稱,可以是相對路徑,絕對路徑或網(wǎng)絡(luò)路徑
nOpenFlags:打開方式有:
·CFile::modeCreate 調(diào)用構(gòu)造函數(shù)構(gòu)造一個(gè)新文件,如果文件已存在,則長度變成0。
·CFile::modeNoTruncate 此值與modeCreate組合使用。如果所創(chuàng)建的文件已存在則其長度不變?yōu)?。因而此文件被打開,或者作為一個(gè)新 文件或者作為一個(gè)已存在的文件。這將是很有用的,例如當(dāng)打開一個(gè)可能存在也可能不存在的文件時(shí)。
·CFile::modeRead 打開文件僅供讀。
·CFile::modeReadWrite 打開文件供讀寫。
·CFile::modeWrite 打開文件僅供寫。
·CFile::modeNoInherit 阻止文件被子進(jìn)程繼承。
·CFile::ShareDenyNone 不禁止其它進(jìn)程讀或?qū)懺L問,打開文件。如果文件已被其它進(jìn)程以兼容模式打開,則Create失敗。
·CFile::ShareDenyRead 打開文件,禁止其它進(jìn)程讀此文件。如果文件已被其它進(jìn)程以兼容模式打開,或被其它進(jìn)程讀,則Create失敗。
·CFile::ShareDenyWrite 打開文件,禁止其它進(jìn)程寫此文件。如果文件已被其它進(jìn)程以兼容模式打開,或被其它進(jìn)程寫,則Create失敗
。
·CFile::ShareExclusive 以獨(dú)占模式打開文件,禁止其它進(jìn)程對文件的讀寫。如果文件已經(jīng)以淥J醬蚩列矗詞貢壞鼻敖蹋?
則構(gòu)造失敗。
·CFile::ShareCompat 此標(biāo)志在32位MFC中無效。此標(biāo)志在使用CFile:: Open時(shí)映射為CFile::ShareExclusive。
·CFile::typeText 對回車換行設(shè)置特殊進(jìn)程(僅用于派生類)。
·CFile::typeBinary 設(shè)置二進(jìn)制模式(僅用于派生類)。
下面給出MSDN中的一個(gè)例子:
char* pFileName = "test.dat";
TRY
{
CFile f( pFileName, CFile::modeCreate | CFile::modeWrite );
}
CATCH( CFileException, e )
{
#ifdef _DEBUG
afxDump << "File could not be opened " << e->m_cause << "\n";
#endif
}
END_CATCH
CFile fileTest;
char* pFileName = "test.dat";
TRY
{
fileTest.Open(pFileName, CFile::modeCreate |CFile::modeWrite);
}
CATCH_ALL(e)
{
fileTest.Abort( );
THROW_LAST ( );
}
END_CATCH_ALL