封装file类
CreateFile中的一个参数,GENERIC_ALL不等于GENERIC_READ加GENERIC_WRITE,ALL还包括更多的权限,使用ALL很可能导致CreateFile失败,一般使用精准的权限
#include<Windows.h>
#include<tchar.h>
class WindowsException//:public std::exception
{
public:
WindowsException(DWORD dwErrorCode):m_dwErrorCode(dwErrorCode)
{
FormatMessage(FORMAT_MESASGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,nullptr,m_dwErrorCode,0,reinterpret_cast(LPWSTR)(&m_strErrorMsg),0,nullptr);
}
~WindowsException()
{
LocalFree(m_dwErrorMsg);
}
const TCHAR* what() const//如果继承了exception,那么what是虚函数,不支持TCHAR,解决办法有两个:改变函数名,比如变为what_unicode,还有一种方法就是不要从exception进行继承
{
return m_dwErrorMsg;
}
private:
DWORD m_dwErrorCode;
TCHAR* m_strErrorMsg;
}
class MyFile
{
public:
MyFile(const TCHAR *strFilePath=TEXT("")):m_hFile(INVALID_HANDLE_VALUE)
{
SetPath(strFilePath);
}
~MyFile()
{
if(m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
}
}
BOOL OpenFile( _In_ DWORD dwDesiredAccess = GENERIC_READ |GENERIC_WRITE,
_In_ DWORD dwShareMode =FILE_SHARE_READ,
_In_ DWORD dwCreationDisposition=OPEN_ALWAYS,
_In_ DWORD dwFlagsAndAttributes=FILE_ATTRIBUTE_NOMAL,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes=nullptr,
_In_opt_ HANDLE hTemplateFile=nullptr)
{
BOOL bRet=TRUE;
m_hFile=CreateFile(m_strFilePath,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
if(m_hFile == INVALID_HANDLE_VALUE)
{
bRet=FALSE;
throw WindowsException(GetLastError());
}
return bRet;
}
VOID SetPath(const TCHAR* strFilePath)
{
SIZE_T nstrlen=_tcslen(strFilePath)+sizeof(TCHAR)
m_strFilePath=new TCHAR[nstrlen]
_stcscpy_s(m_strFilePath,nstrlen,strFilePath);
}
const TCHAR* GetPath() const
{
return m_strFilePath;
}
private:
HANDLE m_hFile;
TCHAR* m_strFilePath;
}
int main()
{
try
{
MyFile clsFile;
clsFile.SetPath(TEXT("demo.txt"))
clsFile.OpenFile();
}
catch(WindowsException &exception)
{
MessageBox(nullptr,exception.what(),exception.what(),MB_OK);
}
return 0;
}
上述代码中,对CreateFile进行了一次封装,为了使得程序更加健壮,在CreateFile失败的时候能够有提示,所有做了一个异常类,对异常进行处理
获取文件大小
大小
分两种:物理大小和磁盘上大小
物理大小
使用GetFileSizeEx()进行获取,用结构体LARGE_INTEGER进行承载,如:
LARGE_INTEGER test={0};
GetFileSizeEx(clsFile.GetHandle(),&test);大小:test.QuadPart
磁盘上占用的大小(可能会压缩)
使用GetCompressedFileSize()获取,用结构体LARGE_INTEGER进行承载,如:
LARGE_INTEGER test={0};
GetCompressedFileSize(clsFile.GetPath(),(LPDWORD)(&(test.HighPart)));注意:高位写入test.HighPart,分成两位返回,返回值是低位,如果要组成一个完整的值,则应该用test.LowPart接收返回值
一般来说物理大小和磁盘大小是一样的