📄 file.cpp
字号:
// File1.cpp: implementation of the CFile class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "File.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFile::CFile()
{
m_hFile = (UINT) hFileNull;
m_bCloseOnDelete = FALSE;
}
CFile::CFile(int hFile)
{
m_hFile = hFile;
m_bCloseOnDelete = FALSE;
}
CFile::CFile(LPCTSTR lpszFileName, UINT nOpenFlags)
{
ATLASSERT(lpszFileName);
CFileException e;
Open(lpszFileName, nOpenFlags, &e);
// AfxThrowFileException(e.m_cause, e.m_lOsError, e.m_strFileName);
}
CFile::~CFile()
{
if (m_hFile != (UINT)hFileNull && m_bCloseOnDelete)
Close();
}
BOOL CFile::Open(LPCTSTR lpszFileName, UINT nOpenFlags,
CFileException* pException)
{
ASSERT(this);
ASSERT(lpszFileName);
// ASSERT(pException == NULL );//||
//AfxIsValidAddress(pException, sizeof(CFileException)));
ASSERT((nOpenFlags & typeText) == 0); // text mode not supported
// CFile objects are always binary and CreateFile does not need flag
nOpenFlags &= ~(UINT)typeBinary;
m_bCloseOnDelete = FALSE;
m_hFile = (UINT)hFileNull;
m_strFileName.Empty();
// TCHAR szTemp[_MAX_PATH];
// AfxFullPath(szTemp, lpszFileName);
// m_strFileName = szTemp;
ASSERT(sizeof(HANDLE) == sizeof(UINT));
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;
// attempt file creation
HANDLE hFile = ::CreateFile(lpszFileName, dwAccess, dwShareMode, &sa,
dwCreateFlag, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if (pException != NULL)
{
pException->m_cause = ::GetLastError();
// pException->m_cause =
// CFileException::OsErrorToException(pException->m_lOsError);
// use passed file name (not expanded vesion) when reporting
// an error while opening
// pException->m_strFileName = lpszFileName;
}
return FALSE;
}
m_hFile = (HFILE)hFile;
m_bCloseOnDelete = TRUE;
return TRUE;
}
UINT CFile::Read(void* lpBuf, UINT nCount)
{
ATLASSERT(this);
ATLASSERT(m_hFile != (UINT)hFileNull);
if (nCount == 0)
return 0; // avoid Win32 "null-read"
ASSERT(lpBuf != NULL);
DWORD dwRead;
if (!::ReadFile((HANDLE)m_hFile, lpBuf, nCount, &dwRead, NULL))
return (DWORD)-1;
// CFileException::ThrowOsError((LONG)::GetLastError());
return (UINT)dwRead;
}
UINT CFile::Write(const void* lpBuf, UINT nCount)
{
ASSERT(this);
ASSERT(m_hFile != (UINT)hFileNull);
if (nCount == 0)
return 0; // avoid Win32 "null-write" option
ASSERT(lpBuf != NULL);
// ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
DWORD nWritten;
if (!::WriteFile((HANDLE)m_hFile, lpBuf, nCount, &nWritten, NULL))
return (DWORD)-1;
return nWritten;
// CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
// Win32s will not return an error all the time (usually DISK_FULL)
// if (nWritten != nCount)
// AfxThrowFileException(CFileException::diskFull, -1, m_strFileName);
}
LONG CFile::Seek(LONG lOff, UINT nFrom)
{
ASSERT(this);
ASSERT(m_hFile != (UINT)hFileNull);
ASSERT(nFrom == begin || nFrom == end || nFrom == current);
ASSERT(begin == FILE_BEGIN && end == FILE_END && current == FILE_CURRENT);
DWORD dwNew = ::SetFilePointer((HANDLE)m_hFile, lOff, NULL, (DWORD)nFrom);
// if (dwNew == (DWORD)-1)
// CFileException::ThrowOsError((LONG)::GetLastError());
return dwNew;
}
DWORD CFile::GetPosition() const
{
ASSERT(this);
ASSERT(m_hFile != (UINT)hFileNull);
DWORD dwPos = ::SetFilePointer((HANDLE)m_hFile, 0, NULL, FILE_CURRENT);
// if (dwPos == (DWORD)-1)
// CFileException::ThrowOsError((LONG)::GetLastError());
return dwPos;
}
void CFile::Flush()
{
ASSERT(this);
if (m_hFile == (UINT)hFileNull)
return;
BOOL bError = ::FlushFileBuffers((HANDLE)m_hFile);
ASSERT(bError);
// if (!::FlushFileBuffers((HANDLE)m_hFile))
// CFileException::ThrowOsError((LONG)::GetLastError());
}
void CFile::Close()
{
ASSERT(this);
ASSERT(m_hFile != (UINT)hFileNull);
BOOL bError = FALSE;
if (m_hFile != (UINT)hFileNull)
bError = !::CloseHandle((HANDLE)m_hFile);
m_hFile = (UINT) hFileNull;
m_bCloseOnDelete = FALSE;
m_strFileName.Empty();
}
void CFile::Abort()
{
ASSERT(this);
if (m_hFile != (UINT)hFileNull)
{
// close but ignore errors
::CloseHandle((HANDLE)m_hFile);
m_hFile = (UINT)hFileNull;
}
m_strFileName.Empty();
}
void CFile::SetLength(DWORD dwNewLen)
{
ATLASSERT(this);
ATLASSERT(m_hFile != (UINT)hFileNull);
Seek((LONG)dwNewLen, (UINT)begin);
::SetEndOfFile((HANDLE)m_hFile);
// CFileException::ThrowOsError((LONG)::GetLastError());
}
DWORD CFile::GetLength() const
{
ASSERT(this);
DWORD dwLen, dwCur;
// Seek is a non const operation
CFile* pFile = (CFile*)this;
dwCur = pFile->Seek(0L, current);
dwLen = pFile->SeekToEnd();
ASSERT(dwCur == (DWORD)pFile->Seek(dwCur, begin));
return dwLen;
}
void PASCAL CFile::Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName)
{
::MoveFile((LPTSTR)lpszOldName, (LPTSTR)lpszNewName);
}
void PASCAL CFile::Remove(LPCTSTR lpszFileName)
{
::DeleteFile((LPTSTR)lpszFileName);
}
/*
CString CFile::GetFileName() const
{
ASSERT_VALID(this);
CFileStatus status;
GetStatus(status);
CString strResult;
AfxGetFileName(status.m_szFullName, strResult.GetBuffer(_MAX_FNAME),
_MAX_FNAME);
strResult.ReleaseBuffer();
return strResult;
}
CString CFile::GetFileTitle() const
{
ASSERT_VALID(this);
CFileStatus status;
GetStatus(status);
CString strResult;
strResult = status.m_szFullName;
return strResult.GetFileTitle();
// AfxGetFileTitle(status.m_szFullName, strResult.GetBuffer(_MAX_FNAME),
// _MAX_FNAME);
// strResult.ReleaseBuffer();
// return strResult;
}
CString CFile::GetFilePath() const
{
ASSERT_VALID(this);
CFileStatus status;
GetStatus(status);
return status.m_szFullName;
}
*/
/////////////////////////////////////////////////////////////////////////////
// CFile Status implementation
/*
BOOL CFile::GetStatus(CFileStatus& rStatus) const
{
ASSERT(this);
memset(&rStatus, 0, sizeof(CFileStatus));
// copy file name from cached m_strFileName
lstrcpyn(rStatus.m_szFullName, m_strFileName,
_countof(rStatus.m_szFullName));
if (m_hFile != hFileNull)
{
// get time current file size
FILETIME ftCreate, ftAccess, ftModify;
if (!::GetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify))
return FALSE;
if ((rStatus.m_size = ::GetFileSize((HANDLE)m_hFile, NULL)) == (DWORD)-1L)
return FALSE;
if (m_strFileName.IsEmpty())
rStatus.m_attribute = 0;
else
{
DWORD dwAttribute = ::GetFileAttributes(m_strFileName);
// don't return an error for this because previous versions of MFC didn't
if (dwAttribute == 0xFFFFFFFF)
rStatus.m_attribute = 0;
else
rStatus.m_attribute = (BYTE) dwAttribute;
}
// convert times as appropriate
rStatus.m_ctime = CTime(ftCreate);
rStatus.m_atime = CTime(ftAccess);
rStatus.m_mtime = CTime(ftModify);
if (rStatus.m_ctime.GetTime() == 0)
rStatus.m_ctime = rStatus.m_mtime;
if (rStatus.m_atime.GetTime() == 0)
rStatus.m_atime = rStatus.m_mtime;
}
return TRUE;
}
*/
//BOOL PASCAL CFile::GetStatus(LPCTSTR lpszFileName, CFileStatus& rStatus)
//{
/* // attempt to fully qualify path first
if (!AfxFullPath(rStatus.m_szFullName, lpszFileName))
{
rStatus.m_szFullName[0] = '\0';
return FALSE;
}
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((LPTSTR)lpszFileName, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
return FALSE;
VERIFY(FindClose(hFind));
// strip attribute of NORMAL bit, our API doesn't have a "normal" bit.
rStatus.m_attribute = (BYTE)
(findFileData.dwFileAttributes & ~FILE_ATTRIBUTE_NORMAL);
// get just the low DWORD of the file size
ASSERT(findFileData.nFileSizeHigh == 0);
rStatus.m_size = (LONG)findFileData.nFileSizeLow;
// convert times as appropriate
rStatus.m_ctime = CTime(findFileData.ftCreationTime);
rStatus.m_atime = CTime(findFileData.ftLastAccessTime);
rStatus.m_mtime = CTime(findFileData.ftLastWriteTime);
if (rStatus.m_ctime.GetTime() == 0)
rStatus.m_ctime = rStatus.m_mtime;
if (rStatus.m_atime.GetTime() == 0)
rStatus.m_atime = rStatus.m_mtime;
return TRUE;
}
void PASCAL CFile::SetStatus(LPCTSTR lpszFileName, const CFileStatus& status)
{
DWORD wAttr;
FILETIME creationTime;
FILETIME lastAccessTime;
FILETIME lastWriteTime;
LPFILETIME lpCreationTime = NULL;
LPFILETIME lpLastAccessTime = NULL;
LPFILETIME lpLastWriteTime = NULL;
if ((wAttr = GetFileAttributes((LPTSTR)lpszFileName)) == (DWORD)-1L)
CFileException::ThrowOsError((LONG)GetLastError());
if ((DWORD)status.m_attribute != wAttr && (wAttr & readOnly))
{
// Set file attribute, only if currently readonly.
// This way we will be able to modify the time assuming the
// caller changed the file from readonly.
SetFileAttributes((LPTSTR)lpszFileName, (DWORD)status.m_attribute);
// if (!SetFileAttributes((LPTSTR)lpszFileName, (DWORD)status.m_attribute))
// CFileException::ThrowOsError((LONG)GetLastError());
}
// last modification time
if (status.m_mtime.GetTime() != 0)
{
AfxTimeToFileTime(status.m_mtime, &lastWriteTime);
lpLastWriteTime = &lastWriteTime;
// last access time
if (status.m_atime.GetTime() != 0)
{
AfxTimeToFileTime(status.m_atime, &lastAccessTime);
lpLastAccessTime = &lastAccessTime;
}
// create time
if (status.m_ctime.GetTime() != 0)
{
AfxTimeToFileTime(status.m_ctime, &creationTime);
lpCreationTime = &creationTime;
}
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
CFileException::ThrowOsError((LONG)::GetLastError());
if (!SetFileTime((HANDLE)hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime))
CFileException::ThrowOsError((LONG)::GetLastError());
if (!::CloseHandle(hFile))
CFileException::ThrowOsError((LONG)::GetLastError());
}
if ((DWORD)status.m_attribute != wAttr && !(wAttr & readOnly))
{
if (!SetFileAttributes((LPTSTR)lpszFileName, (DWORD)status.m_attribute))
CFileException::ThrowOsError((LONG)GetLastError());
}
}
*/
// CFile
DWORD CFile::ReadHuge(void* lpBuffer, DWORD dwCount)
{ return (DWORD)Read(lpBuffer, (UINT)dwCount); }
void CFile::WriteHuge(const void* lpBuffer, DWORD dwCount)
{ Write(lpBuffer, (UINT)dwCount); }
DWORD CFile::SeekToEnd()
{ return Seek(0, CFile::end); }
void CFile::SeekToBegin()
{ Seek(0, CFile::begin); }
/*
void CFile::SetFilePath(LPCTSTR lpszNewName)
{
ASSERT_VALID(this);
ASSERT(lpszNewName != NULL);
m_strFileName = lpszNewName;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -