当前位置:首页 > 编程开发

MFC CFile

webgou16年前 (2010-07-15)编程开发850
class CFile : public CObject { DECLARE_DYNAMIC(CFile) public: // Flag values enum OpenFlags { modeRead = (int) 0x00000, modeWrite = (int) 0x00001, modeReadWrite = (int) 0x00002, shareCompat = (int) 0x00000, shareExclusive = (int) 0x00010, shareDenyWrite = (int) 0x00020, shareDenyRead = (int) 0x00030, shareDenyNone = (int) 0x00040, modeNoInherit = (int) 0x00080, modeCreate = (int) 0x01000, modeNoTruncate = (int) 0x02000, typeText = (int) 0x04000, // typeText and typeBinary are typeBinary = (int) 0x08000, // used in derived classes only osNoBuffer = (int) 0x10000, osWriteThrough = (int) 0x20000, osRandomAccess = (int) 0x40000, osSequentialScan = (int) 0x80000, }; enum Attribute { normal = 0x00, readOnly = 0x01, hidden = 0x02, system = 0x04, volume = 0x08, directory = 0x10, archive = 0x20 }; enum SeekPosition { begin = 0x0, current = 0x1, end = 0x2 }; static AFX_DATA const HANDLE hFileNull; // Constructors CFile(); CFile(HANDLE hFile); CFile(LPCTSTR lpszFileName, UINT nOpenFlags); // Attributes HANDLE m_hFile; operator HANDLE() const; virtual ULONGLONG GetPosition() const; BOOL GetStatus(CFileStatus& rStatus) const; virtual CString GetFileName() const; virtual CString GetFileTitle() const; virtual CString GetFilePath() const; virtual void SetFilePath(LPCTSTR lpszNewName); // Operations virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL); static void PASCAL Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName); static void PASCAL Remove(LPCTSTR lpszFileName); static BOOL PASCAL GetStatus(LPCTSTR lpszFileName, CFileStatus& rStatus); static void PASCAL SetStatus(LPCTSTR lpszFileName, const CFileStatus& status); ULONGLONG SeekToEnd(); void SeekToBegin(); // Overridables #ifndef _WIN32_WCE // Unsupported feature virtual CFile* Duplicate() const; #endif // !_WIN32_WCE virtual ULONGLONG Seek(LONGLONG lOff, UINT nFrom); virtual void SetLength(ULONGLONG dwNewLen); virtual ULONGLONG GetLength() const; virtual UINT Read(void* lpBuf, UINT nCount); virtual void Write(const void* lpBuf, UINT nCount); #ifndef _WIN32_WCE // Unsupported Win32 API call virtual void LockRange(ULONGLONG dwPos, ULONGLONG dwCount); virtual void UnlockRange(ULONGLONG dwPos, ULONGLONG dwCount); #endif // !_WIN32_WCE virtual void Abort(); virtual void Flush(); virtual void Close(); // Implementation public: virtual ~CFile(); #ifdef _DEBUG virtual void AssertValid() const; #ifndef _WIN32_WCE virtual void Dump(CDumpContext& dc) const; #endif // !_WIN32_WCE #endif enum BufferCommand { bufferRead, bufferWrite, bufferCommit, bufferCheck }; enum BufferFlags { bufferDirect = 0x01, bufferBlocking = 0x02 }; virtual UINT GetBufferPtr(UINT nCommand, UINT nCount = 0, void** ppBufStart = NULL, void** ppBufMax = NULL); protected: BOOL m_bCloseOnDelete; CString m_strFileName; }; const HANDLE CFile::hFileNull = INVALID_HANDLE_VALUE; CFile::CFile() { m_hFile = INVALID_HANDLE_VALUE; m_bCloseOnDelete = FALSE; } CFile::CFile(HANDLE hFile) { ASSERT(hFile != INVALID_HANDLE_VALUE); #ifdef _DEBUG DWORD dwFlags=0; ASSERT(GetHandleInformation(hFile,&dwFlags) != 0 ); #endif m_hFile = hFile; m_bCloseOnDelete = FALSE; } CFile::CFile(LPCTSTR lpszFileName, UINT nOpenFlags) { ASSERT(AfxIsValidString(lpszFileName)); m_hFile = INVALID_HANDLE_VALUE; CFileException e; if (!Open(lpszFileName, nOpenFlags, &e)) AfxThrowFileException(e.m_cause, e.m_lOsError, e.m_strFileName); } CFile::~CFile() { AFX_BEGIN_DESTRUCTOR if (m_hFile != INVALID_HANDLE_VALUE && m_bCloseOnDelete) Close(); AFX_END_DESTRUCTOR } CFile* CFile::Duplicate() const { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); CFile* pFile = new CFile(); HANDLE hFile; if (!::DuplicateHandle(::GetCurrentProcess(), m_hFile, ::GetCurrentProcess(), &hFile, 0, FALSE, DUPLICATE_SAME_ACCESS)) { delete pFile; CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); } pFile->m_hFile = hFile; ASSERT(pFile->m_hFile != INVALID_HANDLE_VALUE); pFile->m_bCloseOnDelete = m_bCloseOnDelete; return pFile; } BOOL CFile::Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pException) { ASSERT_VALID(this); ASSERT(AfxIsValidString(lpszFileName)); ASSERT(pException == NULL || AfxIsValidAddress(pException, sizeof(CFileException))); ASSERT((nOpenFlags & typeText) == 0); // text mode not supported // shouldn't open an already open file (it will leak) ASSERT(m_hFile == INVALID_HANDLE_VALUE); // CFile objects are always binary and CreateFile does not need flag nOpenFlags &= ~(UINT)typeBinary; m_bCloseOnDelete = FALSE; m_hFile = INVALID_HANDLE_VALUE; m_strFileName.Empty(); TCHAR szTemp[_MAX_PATH]; if (lpszFileName != NULL && SUCCEEDED(StringCchLength(lpszFileName, _MAX_PATH, NULL)) ) { if( _AfxFullPath2(szTemp, lpszFileName,pException) == FALSE ) return FALSE; } else { // user passed in a buffer greater then _MAX_PATH if (pException != NULL) { pException->m_cause = CFileException::badPath; pException->m_strFileName = lpszFileName; } return FALSE; // path is too long } m_strFileName = szTemp; ASSERT(shareCompat == 0); // map read/write mode ASSERT((modeRead|modeWrite|modeReadWrite) == 3); DWORD dwAccess = 0; switch (nOpenFlags & 3) { case modeRead: dwAccess = GENERIC_READ; break; case modeWrite: dwAccess = GENERIC_WRITE; break; case modeReadWrite: dwAccess = GENERIC_READ | GENERIC_WRITE; break; default: ASSERT(FALSE); // invalid share mode } // map share mode DWORD dwShareMode = 0; switch (nOpenFlags & 0x70) // map compatibility mode to exclusive { default: ASSERT(FALSE); // invalid share mode? case shareCompat: case shareExclusive: dwShareMode = 0; break; case shareDenyWrite: dwShareMode = FILE_SHARE_READ; break; case shareDenyRead: dwShareMode = FILE_SHARE_WRITE; break; case shareDenyNone: dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ; break; } // Note: typeText and typeBinary are used in derived classes only. // map modeNoInherit flag SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = (nOpenFlags & modeNoInherit) == 0; // map creation flags DWORD dwCreateFlag; if (nOpenFlags & modeCreate) { if (nOpenFlags & modeNoTruncate) dwCreateFlag = OPEN_ALWAYS; else dwCreateFlag = CREATE_ALWAYS; } else dwCreateFlag = OPEN_EXISTING; // special system-level access flags // Random access and sequential scan should be mutually exclusive ASSERT((nOpenFlags&(osRandomAccess|osSequentialScan)) != (osRandomAccess| osSequentialScan) ); DWORD dwFlags = FILE_ATTRIBUTE_NORMAL; if (nOpenFlags & osNoBuffer) dwFlags |= FILE_FLAG_NO_BUFFERING; if (nOpenFlags & osWriteThrough) dwFlags |= FILE_FLAG_WRITE_THROUGH; if (nOpenFlags & osRandomAccess) dwFlags |= FILE_FLAG_RANDOM_ACCESS; if (nOpenFlags & osSequentialScan) dwFlags |= FILE_FLAG_SEQUENTIAL_SCAN; // attempt file creation HANDLE hFile = ::CreateFile(lpszFileName, dwAccess, dwShareMode, &sa, dwCreateFlag, dwFlags, NULL); if (hFile == INVALID_HANDLE_VALUE) { _AfxFillExceptionInfo(pException,lpszFileName); return FALSE; } m_hFile = hFile; m_bCloseOnDelete = TRUE; return TRUE; } UINT CFile::Read(void* lpBuf, UINT nCount) { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); if (nCount == 0) return 0; // avoid Win32 "null-read" ASSERT(lpBuf != NULL); ASSERT(AfxIsValidAddress(lpBuf, nCount)); DWORD dwRead; if (!::ReadFile(m_hFile, lpBuf, nCount, &dwRead, NULL)) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); return (UINT)dwRead; } void CFile::Write(const void* lpBuf, UINT nCount) { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); if (nCount == 0) return; // avoid Win32 "null-write" option ASSERT(lpBuf != NULL); ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE)); DWORD nWritten; if (!::WriteFile(m_hFile, lpBuf, nCount, &nWritten, NULL)) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); if (nWritten != nCount) AfxThrowFileException(CFileException::diskFull, -1, m_strFileName); } ULONGLONG CFile::Seek(LONGLONG lOff, UINT nFrom) { ASSERT_VALID(this); ASSERT(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(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 CFile::GetPosition() const { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); LARGE_INTEGER liPos; liPos.QuadPart = 0; liPos.LowPart = ::SetFilePointer(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 CFile::Flush() { ASSERT_VALID(this); if (m_hFile == INVALID_HANDLE_VALUE) return; if (!::FlushFileBuffers(m_hFile)) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); } void CFile::Close() { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); BOOL bError = FALSE; if (m_hFile != INVALID_HANDLE_VALUE) bError = !::CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; m_bCloseOnDelete = FALSE; m_strFileName.Empty(); if (bError) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); } void CFile::Abort() { ASSERT_VALID(this); if (m_hFile != INVALID_HANDLE_VALUE) { // close but ignore errors ::CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; } m_strFileName.Empty(); } void CFile::LockRange(ULONGLONG dwPos, ULONGLONG dwCount) { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); ULARGE_INTEGER liPos; ULARGE_INTEGER liCount; liPos.QuadPart = dwPos; liCount.QuadPart = dwCount; if (!::LockFile(m_hFile, liPos.LowPart, liPos.HighPart, liCount.LowPart, liCount.HighPart)) { CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); } } void CFile::UnlockRange(ULONGLONG dwPos, ULONGLONG dwCount) { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); ULARGE_INTEGER liPos; ULARGE_INTEGER liCount; liPos.QuadPart = dwPos; liCount.QuadPart = dwCount; if (!::UnlockFile(m_hFile, liPos.LowPart, liPos.HighPart, liCount.LowPart, liCount.HighPart)) { CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); } } void CFile::SetLength(ULONGLONG dwNewLen) { ASSERT_VALID(this); ASSERT(m_hFile != INVALID_HANDLE_VALUE); Seek(dwNewLen, (UINT)begin); if (!::SetEndOfFile(m_hFile)) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); } ULONGLONG CFile::GetLength() const { ASSERT_VALID(this); ULARGE_INTEGER liSize; liSize.LowPart = ::GetFileSize(m_hFile, &liSize.HighPart); if (liSize.LowPart == INVALID_FILE_SIZE) if (::GetLastError() != NO_ERROR) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); return liSize.QuadPart; } // CFile does not support direct buffering (CMemFile does) UINT CFile::GetBufferPtr(UINT nCommand, UINT /*nCount*/, void** /*ppBufStart*/, void** /*ppBufMax*/) { ASSERT(nCommand == bufferCheck); UNUSED(nCommand); // not used in retail build return 0; // no support } void PASCAL CFile::Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName) { if (!::MoveFile((LPTSTR)lpszOldName, (LPTSTR)lpszNewName)) CFileException::ThrowOsError((LONG)::GetLastError(), lpszOldName); } void PASCAL CFile::Remove(LPCTSTR lpszFileName) { if (!::DeleteFile((LPTSTR)lpszFileName)) CFileException::ThrowOsError((LONG)::GetLastError(), lpszFileName); }

扫描二维码推送至手机访问。

版权声明:本文由知了博客发布,如需转载请注明出处。

本文链接:https://www.webgou.info/?id=174

标签: MFC
分享给朋友:

“MFC CFile ” 的相关文章

Android屏幕大小相关技巧应用指南

Android应用程序中屏幕大小的设置大家应该都比较清楚,不过如何才能让屏幕自己适应环境而改变大小呢?在这里我们就可以为大家详细介绍一下有关Android屏幕大小的自适应方式,帮助大家理解。不同的Android target会有不同的大小,应用程序的界面需要针对不同的大小调整界面元素的尺寸。而且An…

主流 AI 代码助手功能分析(2026年3月)

 一、市场概览AI 代码助手已从"补全工具"进化为"编程代理",核心趋势:从补全到 Agent:能自主完成完整功能、跑测试、提交 PRIDE 深度整合:Cursor、Windsurf 直接 fork VSCode多模型路由:GPT-4o、Claude…

Java基于Socket文件传输示例

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解。在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度。废话少说,先来看服务器端的程序。1.服务器端package sterning;impo…

the uml of gof

gang of four `s uml…

ResultSet概论

  这篇文章并没有给出如何使用ResultSet的具体例子,只是从ResultSet的功能性上进行了详细的讲述。希望这篇文章对大家理解ResultSet能够有所帮助。下面就是这篇文章的具体内容。        …

Linux下的CPU利用率计算原理详解

在Linux/Unix下,CPU利用率分为用户态,系统态和空闲态,而CPU利用率是指 CPU执行非系统空闲进程的时间 / CPU总的执行时间。…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。