本文转自:http://tech.sina.com.cn/s/2006-03-06/0937858325.shtml
在VC编程中,操作文件的方法主要有两种:利用API函数和MFC的CFile类。微软在其中封装了文件的一般操作,下面我就介绍一下如何利用这两种方法实现文件操作。
1.创建或打开一个文件
API函数CreateFile可打开和创建文件、管道、邮槽、通信服务、设备以及控制台,但是在此时只是介绍用这个函数怎么实现创建和打开一个文件。
HANDLE CreateFile( LPCTSTR lpFileName, // 要打开的文件名 DWORD dwDesiredAccess, // 文件的操作属性 DWORD dwShareMode, // 文件共享属性 LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 文件安全特性 DWORD dwCreationDisposition, //文件操作 DWORD dwFlagsAndAttributes, // 文件属性 HANDLE hTemplateFile // 如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性 ); |
BOOL CloseHandle(HANDLE hObject // handle to object to close); |
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[] = "这是个刚创建的文件"; ::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); } |
CFile( LPCTSTR lpszFileName, UINT nOpenFlags ); throw( CFileException ); CFile( ); BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL ); |
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 |
DWORD SetFilePointer( HANDLE hFile, //文件的句柄 LONG lDistanceToMove, //字节偏移量r PLONG lpDistanceToMoveHigh, //指定一个长整数变量,其中包含了要使用的一个高双字偏移(一般用来操作大型文件)。可设为零,表示只使用lDistanceToMove DWORD dwMoveMethod //文件定位 ); |
BOOL SetEndOfFile(HANDLE hFile //文件的句柄); |
LONG Seek(LONG lOff,UINT nFrom); throw(CFileException); |
CFile file; BITMAPINFOHEADER bmpinfo; try { file.Open("D:\ToolBar.bmp",CFile::modeRead); file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin); file.Read(&bmpinfo,sizeof(BITMAPINFOHEADER )); CString str; str.Format("位图文件的长是%d,高%d",bmpinfo.biWidth,bmpinfo.biHeight); MessageBox(str); file.Close(); } catch(CFileException *e) { CString str; str.Format("读取数据失败的原因是:%d",e->m_cause); MessageBox("str"); file.Abort(); e->Delete(); } |
BOOL ReadFile( HANDLE hFile, //文件的句柄 LPVOID lpBuffer, //用于保存读入数据的一个缓冲区 DWORD nNumberOfBytesToRead, //要读入的字符数 LPDWORD lpNumberOfBytesRead, //从文件中实际读入的字符数 LPOVERLAPPED lpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL ); |
UINT Read (void* lpBuf,UINT nCount); throw(CFileException);// 返回值是传输到缓冲区的字节数。 |
BOOL WriteFile( HANDLE hFile, //文件的句柄 LPCVOID lpBuffer, //要写入的一个数据缓冲区 DWORD nNumberOfBytesToWrite, //要写入数据的字节数量。如写入零字节,表示什么都不写入,但会更新文件的"上一次修改时间"。 LPDWORD lpNumberOfBytesWritten, //实际写入文件的字节数量 LPOVERLAPPED lpOverlapped // OVERLAPPED,倘若在指FILE_FLAG_OVERLAPPED的前提下打开文件,这个参数就必须引用一个特殊的结构。该结构定义了一次异步写操作。否则,该参数应置为NULL ); void Write(const void* lpBuf,UINT nCount); throw (CFileException); |
CFile file; try { file.Open("d:/my.dat",CFile::modeCreate|CFile::modeWrite); file.SeekToBegin(); char Data[] = "111\n1111"; file.Write(Data,sizeof(Data)); file.Flush(); file.Close(); } catch(CFileException *e) { CString str; str.Format("读取数据失败的原因是:%d",e->m_cause); MessageBox("str"); file.Abort(); e->Delete(); } |
BOOL GetFileTime( HANDLE hFile, // 文件句柄 LPFILETIME lpCreationTime, // 创建时间 LPFILETIME lpLastAccessTime, // 最后访问时间 LPFILETIME lpLastWriteTime // 最后写时间 ); BOOL SetFileTime( HANDLE hFile, CONST FILETIME *lpCreationTime, CONST FILETIME *lpLastAccessTime, CONST FILETIME *lpLastWriteTime ); typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; |
static BOOL PASCAL GetStatus( LPCTSTR lpszFileName, CFileStatus& rStatus ); static void SetStatus( LPCTSTR lpszFileName, const CFileStatus& status ); throw( CFileException ); |
struct CFileStatus { CTime m_ctime; // 文件创建时间 CTime m_mtime; // 文件最近一次修改时间 CTime m_atime; // 文件最近一次访问时间 LONG m_size; // 文件大小 BYTE m_attribute; // 文件属性 BYTE _m_padding; // 没有实际含义,用来增加一个字节 TCHAR m_szFullName[_MAX_PATH]; //绝对路径 #ifdef _DEBUG //实现Dump虚拟函数,输出文件属性 void Dump(CDumpContext& dc) const; #endif }; |
CFileStatus status; char *path = "D:\VSS"; if(CFile::GetStatus( path, status )) { CString cTime,mTime,aTime; cTime = status.m_ctime.Format("文件建立时间:%Y年%m月%d日 %H时%M分%S秒"); mTime = status.m_mtime.Format("文件最近修改时间:%Y年%m月%d日 %H时%M分%S秒"); aTime = status.m_atime.Format("文件最近访问时间:%Y年%m月%d日 %H时%M分%S秒"); CString str; str = cTime + "\n" + mTime +"\n" + aTime ; MessageBox(str); } |
DWORD GetFileAttributes( LPCTSTR lpFileName //文件或文件夹路经 ); BOOL SetFileAttributes( LPCTSTR lpFileName, // 文件名 DWORD dwFileAttributes // 要设置的属性 ); |
enum Attribute { normal, readOnly, hidden, system, volume, directory, archive }; |
HANDLE FindFirstFile( LPCTSTR lpFileName, //文件或文件夹路经r LPWIN32_FIND_DATA lpFindFileData ); BOOL FindNextFile( HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData ); BOOL FindClose(HANDLE hFindFile ); |
typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; //文件属性 FILETIME ftCreationTime; // 文件创建时间 FILETIME ftLastAccessTime; // 文件最后一次访问时间 FILETIME ftLastWriteTime; // 文件最后一次修改时间 DWORD nFileSizeHigh; // 文件长度高32位 DWORD nFileSizeLow; // 文件长度低32位 DWORD dwReserved0; // 系统保留 DWORD dwReserved1; // 系统保留 TCHAR cFileName[ MAX_PATH ]; // 长文件名 TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名 } WIN32_FIND_DATA, *PWIN32_FIND_DATA; |
BOOL GetFileInformationByHandle( HANDLE hFile, // 文件的句柄 LPBY_HANDLE_FILE_INFORMATION lpFileInformation ); |
typedef struct _BY_HANDLE_FILE_INFORMATION { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD dwVolumeSerialNumber; // 文件所在的磁盘的序列号 DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD nNumberOfLinks; //链接的数目 DWORD nFileIndexHigh; DWORD nFileIndexLow; } BY_HANDLE_FILE_INFORMATION; |
HANDLE handle; WIN32_FIND_DATA find_data; handle = :: FindFirstFile("D:\VSS",&find_data); FindClose(handle); find_data.dwFileAttributes = find_data.dwFileAttributes|FILE_ATTRIBUTE_READONLY; ::SetFileAttributes("D:\VSS",find_data.dwFileAttributes); |
在上面的介绍中,除了可以设置文件的属性之外,在操作的过程当中也可以取得文件的其他一些信息,可以根据具体的需要来实现。
5.获取文件名,文件类型,文件长度,文件路径
用利用CFile打开一个文件时,可以在利用成员函数
virtual CString GetFileName( ) const, virtual CString GetFileTitle( ) const, virtual CString GetFilePath( ) const, virtual DWORD GetLength( ) const;throw( CFileException ); |
virtual void SetLength( DWORD dwNewLen );throw( CFileException ); virtual void SetFilePath( LPCTSTR lpszNewName ); |
CFile file("Text.txt",CFile::modeReadWrite); ULONGLONG length; CString strFilePath; length = file.GetLength(); length = length + 1024*10; file.SetLength(length); file.SetFilePath("D:\Text.txt"); strFilePath = file.GetFilePath(); MessageBox(strFilePath); file.Close(); |
CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL ); |
CString FileFilter = "所有文件(*.*)|*.*||"; CFileDialog FileDialog(true,NULL,NULL,OFN_HIDEREADONLY,FileFilter,NULL); FileDialog.DoModal(); MessageBox(FileDialog.GetFileName()); |