VC的文件操作
1.文件的查找
當對一個文件操作時,如果不知道該文件是否存在,就要首先進行查找。MFC中有一個專門用來進行文件查找的類CFileFind,使用它可以方便快捷地進行文件的查找。下面這段代碼演示了這個類的最基本使用方法。
CString strFileTitle;
CFileFind finder;
BOOL bWorking = finder.FindFile("C:\\windows\\sysbkup\\*.cab");
while(bWorking)
{
bWorking=finder.FindNextFile();
strFileTitle=finder.GetFileTitle();
}
2.文件的打開/保存對話框
讓用戶選擇文件進行打開和存儲操作時,就要用到文件打開/保存對話框。MFC的類CFileDialog用于實現這種功能。使用CFileDialog聲明一個對象時,第一個BOOL型參數用于指定文件的打開或保存,當為TRUE時將構造一個文件打開對話框,為FALSE時構造一個文件保存對話框。
在構造CFileDialog對象時,如果在參數中指定了OFN_ALLOWMULTISELECT風格,則在此對話框中可以進行多選操作。此時要重點注意為此CFileDialog對象的m_ofn.lpstrFile分配一塊內存,用于存儲多選操作所返回的所有文件路徑名,如果不進行分配或分配的內存過小就會導致操作失敗。下面這段程序演示了文件打開對話框的使用方法。
CFileDialog mFileDlg(TRUE,NULL,NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
"All Files (*.*)|*.*||",AfxGetMainWnd());
CString str(" ",10000);
mFileDlg.m_ofn.lpstrFile=str.GetBuffer(10000);
str.ReleaseBuffer();
POSITION mPos=mFileDlg.GetStartPosition();
CString pathName(" ",128);
CFileStatus status;
while(mPos!=NULL)
{
pathName=mFileDlg.GetNextPathName(mPos);
CFile::GetStatus( pathName, status );
}
3.文件的讀寫
文件的讀寫非常重要,下面將重點進行介紹。文件讀寫的最普通的方法是直接使用CFile進行,如文件的讀寫可以使用下面的方法:
//對文件進行讀操作
char sRead[2];
CFile mFile(_T("user.txt"),CFile::modeRead);
if(mFile.GetLength()<2)
return;
mFile.Read(sRead,2);
mFile.Close();
//對文件進行寫操作
CFile mFile(_T("user.txt "), CFile::modeWrite|CFile::modeCreate);
mFile.Write(sRead,2);
mFile.Flush();
mFile.Close();
雖然這種方法最為基本,但是它的使用繁瑣,而且功能非常簡單。我向你推薦的是使用CArchive,它的使用方法簡單且功能十分強大。首先還是用CFile聲明一個對象,然后用這個對象的指針做參數聲明一個CArchive對象,你就可以非常方便地存儲各種復雜的數據類型了。它的使用方法見下例。
//對文件進行寫操作
CString strTemp;
CFile mFile;
mFile.Open("d:\\dd\\try.TRY",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
CArchive ar(&mFile,CArchive::store);
ar<< ar.Close();
mFile.Close();
//對文件進行讀操作
CFile mFile;
if(mFile.Open("d:\\dd\\try.TRY",CFile::modeRead)==0)
return;
CArchive ar(&mFile,CArchive::load);
ar>>strTemp;
ar.Close();
mFile.Close();
CArchive的 << 和>> 操作符用于簡單數據類型的讀寫,對于CObject派生類的對象的存取要使用ReadObject()和WriteObject()。使用CArchive的ReadClass()和WriteClass()還可以進行類的讀寫,如:
//存儲CAboutDlg類
ar.WriteClass(RUNTIME_CLASS(CAboutDlg));
//讀取CAboutDlg類
CRuntimeClass* mRunClass=ar.ReadClass();
//使用CAboutDlg類
CObject* pObject=mRunClass->CreateObject();
((CDialog* )pObject)->DoModal();
雖然VC提供的文檔/視結構中的文檔也可進行這些操作,但是不容易理解、使用和管理,因此雖然很多VC入門的書上花費大量篇幅講述文檔/視結構,但我建議你最好不要使用它的文檔。關于如何進行文檔/視的分離有很多書介紹,包括非常著名的《Visual C++ 技術內幕》。
如果你要進行的文件操作只是簡單的讀寫整行的字符串,我建議你使用CStdioFile,用它來進行此類操作非常方便,如下例。
CStdioFile mFile;
CFileException mExcept;
mFile.Open( "d:\\temp\\aa.bat", CFile::modeWrite, &mExcept);
CString string="I am a string.";
mFile.WriteString(string);
mFile.Close();
4.臨時文件的使用
正規軟件經常用到臨時文件,你經常可以會看到C:\Windows\Temp目錄下有大量的擴展名為tmp的文件,這些就是程序運行是建立的臨時文件。臨時文件的使用方法基本與常規文件一樣,只是文件名應該調用函數GetTempFileName()獲得。它的第一個參數是建立此臨時文件的路徑,第二個參數是建立臨時文件名的前綴,第四個參數用于得到建立的臨時文件名。得到此臨時文件名以后,你就可以用它來建立并操作文件了,如:
char szTempPath[_MAX_PATH],szTempfile[_MAX_PATH];
GetTempPath(_MAX_PATH, szTempPath);
GetTempFileName(szTempPath,_T ("my_"),0,szTempfile);
CFile m_tempFile(szTempfile,CFile:: modeCreate|CFile:: modeWrite);
char m_char='a';
m_tempFile.Write(&m_char,2);
m_tempFile.Close();
5.文件的復制、刪除等
MFC中沒有提供直接進行這些操作的功能,因而要使用SDK。SDK中的文件相關函數常用的有CopyFile()、CreateDirectory()、DeleteFile()、MoveFile()。它們的用法很簡單,可參考MSDN。
*********************************************************************************************************************
×××××××××××××××××××××××××××××××××××××××××××××××××
*********************************************************************************************************************
如何進行文件操作
[1]顯示對話框,取得文件名
CString FilePathName;
CFileDialog dlg(TRUE);///TRUE為OPEN對話框,FALSE為SAVE AS對話框
if (dlg.DoModal() == IDOK)
FilePathName=dlg.GetPathName();
相關信息:CFileDialog 用于取文件名的幾個成員函數:
假如選擇的文件是C:\WINDOWS\TEST.EXE
則(1)GetPathName();取文件名全稱,包括完整路徑。取回C:\WINDOWS\TEST.EXE
(2)GetFileTitle();取文件全名:TEST.EXE
(3)GetFileName();取回TEST
(4)GetFileExt();取擴展名EXE
[2]打開文件
CFile file("C:\HELLO.TXT",CFile::modeRead);//只讀方式打開
//CFile::modeRead可改為 CFile::modeWrite(只寫),
//CFile::modeReadWrite(讀寫),CFile::modeCreate(新建)
例子:
{
CFile file;
file.Open("C:\HELLO.TXT",CFile::modeCreate|Cfile::modeWrite);
.
.
.
}
[3]移動文件指針
file.Seek(100,CFile::begin);///從文件頭開始往下移動100字節
file.Seek(-50,CFile::end);///從文件末尾往上移動50字節
file.Seek(-30,CFile::current);///從當前位置往上移動30字節
file.SeekToBegin();///移到文件頭
file.SeekToEnd();///移到文件尾
[4]讀寫文件
讀文件:
char buffer[1000];
file.Read(buffer,1000);
寫文件:
CString string("自強不息");
file.Write(string,8);
[5]關閉文件
file.Close();
在我們寫的程序當中,總有一些配置信息需要保存下來,以便完成程序的功能,最簡單的辦法就是將這些信息寫入INI文件中,程序初始化時再讀入.具體應用如下:
一.將信息寫入.INI文件中.
1.所用的WINAPI函數原型為:
BOOL WritePrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpString,
LPCTSTR lpFileName
);
其中各參數的意義:
LPCTSTR lpAppName 是INI文件中的一個字段名.
LPCTSTR lpKeyName 是lpAppName下的一個鍵名,通俗講就是變量名.
LPCTSTR lpString 是鍵值,也就是變量的值,不過必須為LPCTSTR型或CString型的.
LPCTSTR lpFileName 是完整的INI文件名.
2.具體使用方法:設現有一名學生,需把他的姓名和年齡寫入 c:\stud\student.ini 文件中.
CString strName,strTemp;
int nAge;
strName="張三";
nAge=12;
::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");
此時c:\stud\student.ini文件中的內容如下:
[StudentInfo]
Name=張三
3.要將學生的年齡保存下來,只需將整型的值變為字符型即可:
strTemp.Format("%d",nAge);
::WritePrivateProfileString("StudentInfo","Age",strTemp,"c:\\stud\\student.ini");
二.將信息從INI文件中讀入程序中的變量.
1.所用的WINAPI函數原型為:
DWORD GetPrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpDefault,
LPTSTR lpReturnedString,
DWORD nSize,
LPCTSTR lpFileName
);
其中各參數的意義:
前二個參數與 WritePrivateProfileString中的意義一樣.
lpDefault : 如果INI文件中沒有前兩個參數指定的字段名或鍵名,則將此值賦給變量.
lpReturnedString : 接收INI文件中的值的CString對象,即目的緩存器.
nSize : 目的緩存器的大小.
lpFileName : 是完整的INI文件名.
2.具體使用方法:現要將上一步中寫入的學生的信息讀入程序中.
CString strStudName;
int nStudAge;
GetPrivateProfileString("StudentInfo","Name","默認姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\stud\\student.ini");
執行后 strStudName 的值為:"張三",若前兩個參數有誤,其值為:"默認姓名".
3.讀入整型值要用另一個WINAPI函數:
UINT GetPrivateProfileInt(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
INT nDefault,
LPCTSTR lpFileName
);
這里的參數意義與上相同.使用方法如下:
nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\stud\\student.ini");
三.循環寫入多個值,設現有一程序,要將最近使用的幾個文件名保存下來,具體程序如下:
1.寫入:
CString strTemp,strTempA;
int i;
int nCount=6;
file://共有6個文件名需要保存
for(i=0;i {strTemp.Format("%d",i);
strTempA=文件名;
file://文件名可以從數組,列表框等處取得.
::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,
"c:\\usefile\\usefile.ini");
}
strTemp.Format("%d",nCount);
::WritePrivateProfileString("FileCount","Count",strTemp,"c:\\usefile\\usefile.ini");
file://將文件總數寫入,以便讀出.
2.讀出:
nCount=::GetPrivateProfileInt("FileCount","Count",0,"c:\\usefile\\usefile.ini");
for(i=0;i {strTemp.Format("%d",i);
strTemp="FileName"+strTemp;
::GetPrivateProfileString("CurrentIni",strTemp,"default.fil", strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:\\usefile\\usefile.ini");
file://使用strTempA中的內容.
}
補充四點:
1.INI文件的路徑必須完整,文件名前面的各級目錄必須存在,否則寫入不成功,該函數返回 FALSE 值.
2.文件名的路徑中必須為 \\ ,因為在VC++中, \\ 才表示一個 \ .
3.也可將INI文件放在程序所在目錄,此時 lpFileName 參數為: ".\\student.ini".
//----------------------------------------------------------------------------------
/*
類名:CIni
版本:v2.0
最后更新:
v2.0
夢小孩于2004年2月14日情人節
加入高級操作的功能
v1.0
夢小孩于2003年某日
一般操作完成
類描述:
本類可以于.ini文件進行操作
*/
文件 1:
#pragma once
#include "afxTempl.h"
class CIni
{
private:
CString m_strFileName;
public:
CIni(CString strFileName):m_strFileName(strFileName)
{
}
public:
//一般性操作:
BOOL SetFileName(LPCTSTR lpFileName); //設置文件名
CString GetFileName(void); //獲得文件名
BOOL SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue,bool bCreate=true); //設置鍵值,bCreate是指段名及鍵名未存在時,是否創建。
CString GetValue(LPCTSTR lpSection, LPCTSTR lpKey); //得到鍵值.
BOOL DelSection(LPCTSTR strSection); //刪除段名
BOOL DelKey(LPCTSTR lpSection, LPCTSTR lpKey); //刪除鍵名
public:
//高級操作:
int GetSections(CStringArray& arrSection); //枚舉出全部的段名
int GetKeyValues(CStringArray& arrKey,CStringArray& arrValue,LPCTSTR lpSection); //枚舉出一段內的全部鍵名及值
BOOL DelAllSections();
};
文件 2:
#include "StdAfx.h"
#include "ini.h"
#define MAX_ALLSECTIONS 2048 //全部的段名
#define MAX_SECTION 260 //一個段名長度
#define MAX_ALLKEYS 6000 //全部的鍵名
#define MAX_KEY 260 //一個鍵名長度
BOOL CIni::SetFileName(LPCTSTR lpFileName)
{
CFile file;
CFileStatus status;
if(!file.GetStatus(lpFileName,status))
return TRUE;
m_strFileName=lpFileName;
return FALSE;
}
CString CIni::GetFileName(void)
{
return m_strFileName;
}
BOOL CIni::SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue,bool bCreate)
{
TCHAR lpTemp[MAX_PATH] ={0};
//以下if語句表示如果設置bCreate為false時,當沒有這個鍵名時則返回TRUE(表示出錯)
//!*&*none-value*&!* 這是個垃圾字符沒有特別意義,這樣亂寫是防止湊巧相同。
if (!bCreate)
{
GetPrivateProfileString(lpSection,lpKey,"!*&*none-value*&!*",lpTemp,MAX_PATH,m_strFileName);
if(strcmp(lpTemp,"!*&*none-value*&!*")==0)
return TRUE;
}
if(WritePrivateProfileString(lpSection,lpKey,lpValue,m_strFileName))
return FALSE;
else
return GetLastError();
}
CString CIni::GetValue(LPCTSTR lpSection, LPCTSTR lpKey)
{
DWORD dValue;
TCHAR lpValue[MAX_PATH] ={0};
dValue=GetPrivateProfileString(lpSection,lpKey,"",lpValue,MAX_PATH,m_strFileName);
return lpValue;
}
BOOL CIni::DelSection(LPCTSTR lpSection)
{
if(WritePrivateProfileString(lpSection,NULL,NULL,m_strFileName))
return FALSE;
else
return GetLastError();
}
BOOL CIni::DelKey(LPCTSTR lpSection, LPCTSTR lpKey)
{
if(WritePrivateProfileString(lpSection,lpKey,NULL,m_strFileName))
return FALSE;
else
return GetLastError();
}
int CIni::GetSections(CStringArray& arrSection)
{
/*
本函數基礎:
GetPrivateProfileSectionNames - 從 ini 文件中獲得 Section 的名稱
如果 ini 中有兩個 Section: [sec1] 和 [sec2],則返回的是 'sec1',0,'sec2',0,0 ,當你不知道
ini 中有哪些 section 的時候可以用這個 api 來獲取名稱
*/
int i;
int iPos=0;
int iMaxCount;
TCHAR chSectionNames[MAX_ALLSECTIONS]={0}; //總的提出來的字符串
TCHAR chSection[MAX_SECTION]={0}; //存放一個段名。
GetPrivateProfileSectionNames(chSectionNames,MAX_ALLSECTIONS,m_strFileName);
//以下循環,截斷到兩個連續的0
for(i=0;i<MAX_ALLSECTIONS;i++)
{
if (chSectionNames[i]==0)
if (chSectionNames[i]==chSectionNames[i+1])
break;
}
iMaxCount=i+1; //要多一個0號元素。即找出全部字符串的結束部分。
arrSection.RemoveAll();//清空原數組
for(i=0;i<iMaxCount;i++)
{
chSection[iPos++]=chSectionNames[i];
if(chSectionNames[i]==0)
{
arrSection.Add(chSection);
memset(chSection,0,MAX_SECTION);
iPos=0;
}
}
return (int)arrSection.GetSize();
}
int CIni::GetKeyValues(CStringArray& arrKey,CStringArray& arrValue, LPCTSTR lpSection)
{
/*
本函數基礎:
GetPrivateProfileSection- 從 ini 文件中獲得一個Section的全部鍵名及值名
如果ini中有一個段,其下有 "段1=值1" "段2=值2",則返回的是 '段1=值1',0,'段2=值2',0,0 ,當你不知道
獲得一個段中的所有鍵及值可以用這個。
*/
int i;
int iPos=0;
CString strKeyValue;
int iMaxCount;
TCHAR chKeyNames[MAX_ALLKEYS]={0}; //總的提出來的字符串
TCHAR chKey[MAX_KEY]={0}; //提出來的一個鍵名
GetPrivateProfileSection(lpSection,chKeyNames,MAX_ALLKEYS,m_strFileName);
for(i=0;i<MAX_ALLKEYS;i++)
{
if (chKeyNames[i]==0)
if (chKeyNames[i]==chKeyNames[i+1])
break;
}
iMaxCount=i+1; //要多一個0號元素。即找出全部字符串的結束部分。
arrKey.RemoveAll();//清空原數組
arrValue.RemoveAll();
for(i=0;i<iMaxCount;i++)
{
chKey[iPos++]=chKeyNames[i];
if(chKeyNames[i]==0)
{
strKeyValue=chKey;
arrKey.Add(strKeyValue.Left(strKeyValue.Find("=")));
arrValue.Add(strKeyValue.Mid(strKeyValue.Find("=")+1));
memset(chKey,0,MAX_KEY);
iPos=0;
}
}
return (int)arrKey.GetSize();
}
BOOL CIni::DelAllSections()
{
int nSection;
CStringArray arrSection;
nSection=GetSections(arrSection);
for(int i=0;i<nSection;i++)
{
if(DelSection(arrSection[i]))
return GetLastError();
}
return FALSE;
}
使用方法:
CIni ini("c:\\a.ini");
int n;
/*獲得值
TRACE("%s",ini.GetValue("段1","鍵1"));
*/
/*添加值
ini.SetValue("自定義段","鍵1","值");
ini.SetValue("自定義段2","鍵1","值",false);
*/
/*枚舉全部段名
CStringArray arrSection;
n=ini.GetSections(arrSection);
for(int i=0;i<n;i++)
TRACE("%s\n",arrSection[i]);
*/
/*枚舉全部鍵名及值
CStringArray arrKey,arrValue;
n=ini.GetKeyValues(arrKey,arrValue,"段1");
for(int i=0;i<n;i++)
TRACE("鍵:%s\n值:%s\n",arrKey[i],arrValue[i]);
*/
/*刪除鍵值
ini.DelKey("段1","鍵1");
*/
/*刪除段
ini.DelSection("段1");
*/
/*刪除全部
ini.DelAllSections();
*/
VC++中以追加方式向文本文件寫入數據
在VB、Asp中向文本文件追加數據很容易,只要設定一個參數為ForAppending就行了。
Sub OpenTextFileTest
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile("c:\testfile.txt", ForWriting, True)
f.Write "Hello world!"
f.Close
End Sub
在c語言中,追加數據也比較簡單,好像設定a+參數就可以了。
今天,我要用MFC中的CStdioFile類進行文件操作,讀寫等。
可是,看了下好像沒有簡單的方法,
于是在網上看到這樣的寫法:
CStdioFile file(strFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
file.WriteString(strTmp);
file.Close;
modeNoTruncate的意思就是不要截取的意思吧
可是,試了下這段代碼,并沒有起作用,不知道是什么原因。
于是,在WriteString寫字符串之前加了個把指針先定位到文件末尾的代碼,就可以了
CString strTmp="hehe\r\n";
CStdioFile file(strFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
file.SeekToEnd();//先定位到文件尾部
file.WriteString(strTmp);
file.Close;
隨著Windows 2000和XP的普及,現在的大文件越來越多,而VC6中MFC的CFile類只支持不大于4GB的文件, 原因在于CFile類中使用了32位整型來處理文件,32位數的范圍是2的32次方(4GB),超過這個范圍的文件CFile就管不了,微軟.Net中VC7的CFile類支持大于4GB的文件,而.Net還不普及,開發桌面應用VC6還是首選,所以我們可以參照VC7寫一個CFile的繼承類CFile64,使它支持大于4GB的文件:
class CFile64 : public CFile
{
public:
// Attributes
ULONGLONG GetPosition();
// Overridables
virtual ULONGLONG Seek(LONGLONG lOff, UINT nFrom);
virtual void SetLength(ULONGLONG dwNewLen);
ULONGLONG GetLength() ;
virtual void LockRange(ULONGLONG dwPos, ULONGLONG dwCount);
virtual void UnlockRange(ULONGLONG dwPos, ULONGLONG dwCount);
};
#include "stdafx.h"
#include "file64.h"
////////////////////////////////////////////////////////////////////////////
// CFile64 implementation
ULONGLONG CFile64::Seek(LONGLONG lOff, UINT nFrom)
{
ASSERT_VALID(this);
ASSERT((HANDLE)m_hFile != INVALID_HANDLE_VALUE);
ASSERT(nFrom == begin || nFrom == end || nFrom == current);
ASSERT(begin == FILE_BEGIN && end == FILE_END && current == FILE_CURRENT);
LARGE_INTEGER liOff;
liOff.QuadPart = lOff;
liOff.LowPart = ::SetFilePointer((HANDLE)m_hFile, liOff.LowPart, &liOff.HighPart,
(DWORD)nFrom);
if (liOff.LowPart == (DWORD)-1)
if (::GetLastError() != NO_ERROR)
CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
return liOff.QuadPart;
}
ULONGLONG CFile64::GetPosition()
{
ASSERT_VALID(this);
ASSERT((HANDLE)m_hFile != INVALID_HANDLE_VALUE);
LARGE_INTEGER liPos;
liPos.QuadPart = 0;
liPos.LowPart = ::SetFilePointer((HANDLE)m_hFile, liPos.LowPart, &liPos.HighPart , FILE_CURRENT);
if (liPos.LowPart == (DWORD)-1)
if (::GetLastError() != NO_ERROR)
CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
return liPos.QuadPart;
}
void CFile64::LockRange(ULONGLONG dwPos, ULONGLONG dwCount)
{
ASSERT_VALID(this);
ASSERT((HANDLE)m_hFile != INVALID_HANDLE_VALUE);
ULARGE_INTEGER liPos;
ULARGE_INTEGER liCount;
liPos.QuadPart = dwPos;
liCount.QuadPart = dwCount;
if (!::LockFile((HANDLE)m_hFile, liPos.LowPart, liPos.HighPart, liCount.LowPart,
liCount.HighPart))
{
CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
}
}
void CFile64::UnlockRange(ULONGLONG dwPos, ULONGLONG dwCount)
{
ASSERT_VALID(this);
ASSERT((HANDLE)m_hFile != INVALID_HANDLE_VALUE);
ULARGE_INTEGER liPos;
ULARGE_INTEGER liCount;
liPos.QuadPart = dwPos;
liCount.QuadPart = dwCount;
if (!::UnlockFile((HANDLE)m_hFile, liPos.LowPart, liPos.HighPart, liCount.LowPart,
liCount.HighPart))
{
CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
}
}
void CFile64::SetLength(ULONGLONG dwNewLen)
{
ASSERT_VALID(this);
ASSERT((HANDLE)m_hFile != INVALID_HANDLE_VALUE);
Seek(dwNewLen, (UINT)begin);
if (!::SetEndOfFile((HANDLE)m_hFile))
CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
}
ULONGLONG CFile64::GetLength()
{
ASSERT_VALID(this);
ULARGE_INTEGER liSize;
liSize.LowPart = ::GetFileSize((HANDLE)m_hFile, &liSize.HighPart);
if (liSize.LowPart == (DWORD)-1)
if (::GetLastError() != NO_ERROR)
CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
return liSize.QuadPart;
}
/////////////////////////////////////////////////////////////////////////////
LONGLONG是64位整型,這樣在理論上可支持的最大文件為18000000000GB,你也可以根據自己的需要重載CFile的其他函數
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成