CFileUtils.h
#pragma once
#include <wtypesbase.h>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <tchar.h>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
enum eFileAttributes
{
eReadonly = FILE_ATTRIBUTE_READONLY,
eHidden = FILE_ATTRIBUTE_HIDDEN,
eSystem = FILE_ATTRIBUTE_SYSTEM,
eDirectory = FILE_ATTRIBUTE_DIRECTORY,
eArchive = FILE_ATTRIBUTE_ARCHIVE,
eDevice = FILE_ATTRIBUTE_DEVICE,
eNormal = FILE_ATTRIBUTE_NORMAL,
eTemporary = FILE_ATTRIBUTE_TEMPORARY,
eSparse_file = FILE_ATTRIBUTE_SPARSE_FILE,
eReparse_point = FILE_ATTRIBUTE_REPARSE_POINT,
eCompressed = FILE_ATTRIBUTE_COMPRESSED,
eOffline = FILE_ATTRIBUTE_OFFLINE,
eNot_content_indexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
eEncrypted = FILE_ATTRIBUTE_ENCRYPTED,
eIntegrity_stream = FILE_ATTRIBUTE_INTEGRITY_STREAM,
eVirtual = FILE_ATTRIBUTE_VIRTUAL,
eNo_scrub_data = FILE_ATTRIBUTE_NO_SCRUB_DATA,
eEa = FILE_ATTRIBUTE_EA,
ePinned = FILE_ATTRIBUTE_PINNED,
eUnpinned = FILE_ATTRIBUTE_UNPINNED,
eRecall_on_open = FILE_ATTRIBUTE_RECALL_ON_OPEN,
eRecall_on_data_access = FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS,
};
typedef struct _FILEINFO
{
_tstring m_fileDir;
_tstring m_fileName;
_tstring m_filePath;
unsigned long long m_fileSize;
DWORD m_fileAttributes;
unsigned long long m_ftCreationTime;
unsigned long long m_ftLastAccessTime;
unsigned long long m_ftLastWriteTime;
_FILEINFO() :
m_fileSize(0),
m_fileAttributes(0),
m_ftCreationTime(0),
m_ftLastAccessTime(0),
m_ftLastWriteTime(0)
{
};
}FILEINFO;
class CFileUtils
{
public:
//
// @brief: 获取文件扩展名
// @param: strfileName 文件名, 如: test.exe
// @param: bIncludeDot 是否包含 . 号
// @ret: 扩展名 如 test.exe bIncludeDot = false 时返回 exe, bIncludeDot = true 时返回 .exe,
static _tstring GetFileExtName(
const _tstring& strfileName,
bool bIncludeDot = false
);
//
// @brief: 获取目录下文件路径
// @param: fileList 文件路径字符串容器
// @param: strDir 指定目录
// @param: extList 扩展名过滤列表, 如: {("exe"), ("txt")}
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: bIgnoreCase 是否忽略扩展名过滤大小写
// @ret: void
static void GetFileList(
std::vector<_tstring>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
bool bIgnoreCase = true
);
//
// @brief: 获取目录下文件路径
// @param: fileList 文件路径字符串容器
// @param: strDir 指定目录
// @param: extList 扩展名过滤列表, 如: {("exe"), ("txt")}
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: bIgnoreCase 是否忽略扩展名过滤大小写
// @ret: void
static void GetFileList(
std::set<_tstring>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
bool bIgnoreCase = true
);
//
// @brief: 获取目录下文件路径
// @param: fileList 文件信息容器
// @param: strDir 指定目录
// @param: extList 扩展名过滤列表, 如: {("exe"), ("txt")}
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: bIgnoreCase 是否忽略扩展名过滤大小写
// @ret: void
static void GetFileList(
std::map<_tstring, FILEINFO>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
bool bIgnoreCase = true
);
//
// @brief: 获取目录下子目录
// @param: fileList 文件信息容器
// @param: strDir 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @ret: void
static void GetDirList(
std::vector<_tstring>& fileList,
const _tstring& strDir,
int32_t depth = MAX_PATH
);
//
// @brief: 获取目录下文件路径
// @param: fileList 文件信息容器
// @param: strDir 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @ret: void
static void GetDirList(
std::map<_tstring, FILEINFO>& dirList,
const _tstring& strDir,
int32_t depth = MAX_PATH
);
//
// @brief: 检查路径是否存在
// @param: strPath 路径
// @ret: 存在返回true
static bool IsExist(const _tstring& strPath);
//
// @brief: 检查路径是否隐藏
// @param: strPath 路径
// @ret: 隐藏返回true
static bool IsHidden(const _tstring& strPath);
//
// @brief: 检查路径是否是存档
// @param: strPath 路径
// @ret: 存档返回true
static bool IsArchive(const _tstring& strPath);
//
// @brief: 检查路径是否是只读
// @param: strPath 路径
// @ret: 只读返回true
static bool IsReadOnly(const _tstring& strPath);
//
// @brief: 检查路径是否是目录
// @param: strPath 路径
// @ret: 目录返回true
static bool IsDirectory(const _tstring& strPath);
//
// @brief: 获取路径属性
// @param: strPath 路径
// @ret: 成功返回true
static bool GetAttributes(const _tstring& strPath, DWORD& dwAttr);
//
// @brief: 设置路径属性
// @param: strPath 路径
// @ret: 成功返回true
static bool SetAttributes(const _tstring& strPath, const DWORD& dwAttr);
//
// @brief: 获取文件大小
// @param: strPath 路径
// @ret: 文件大小
static unsigned long long GetFileSize(const _tstring& strPath);
//
// @brief: 删除文件
// @param: strPath 路径
// @ret: 成功返回true
static bool DeleteArchive(const _tstring& strPath);
//
// @brief: 删除目录(递归删除子目录及文件)
// @param: strPath 路径
// @ret: 成功返回true
static bool DeleteDir(const _tstring& strPath);
//
// @brief: 创建目录(递归)
// @param: strPath 路径
// @ret: 成功返回true
static bool CreateDir(const _tstring& strPath);
};
class CFileHelper
{
public:
static bool GetAttributes(const _tstring& strPath, DWORD& dwAttr);
static bool SetAttributes(const _tstring& strPath, const DWORD& dwAttr);
public:
CFileHelper();
CFileHelper(const CFileHelper&) = delete;
CFileHelper(const _tstring& strPath, bool bReadonly = false);
~CFileHelper();
bool Open(const _tstring& strPath, bool bCreateIfNoExist = true, bool bReadonly = false);
void Close();
bool IsOpen() const;
bool GetSize(unsigned long long& ullSize) const;
bool GetAttributes(DWORD& dwAttr) const;
bool SetAttributes(const DWORD& dwAttr) const;
LONGLONG GetPointer() const;
bool SetPointer(LONGLONG llPos = 0, DWORD dwFlag = FILE_CURRENT);
bool Read(LPVOID lpBuffer, DWORD dwSize, LONGLONG llPos = 0, LPDWORD lpBytesRead = nullptr, DWORD dwFlag = FILE_CURRENT);
bool Write(LPCVOID lpBuffer, DWORD dwSize, LONGLONG llPos = 0, LPDWORD lpBytesWritten = nullptr, DWORD dwFlag = FILE_CURRENT);
bool Clear();
bool SetEnd(LONGLONG llPos);
private:
HANDLE m_hFile;
_tstring m_strFile;
};
CFileUtils.cpp
#include "CFileUtils.h"
#include <io.h>
_tstring CFileUtils::GetFileExtName(const _tstring& strfileName, bool bIncludeDot/* = false*/)
{
_tstring strExtName = strfileName;
size_t nExtPos = strExtName.find_last_of(_T('.'));
if (_tstring::npos == nExtPos)
{
return _T("");
}
if (bIncludeDot)
{
strExtName.erase(0, nExtPos);
}
else
{
strExtName.erase(0, nExtPos + 1);
}
return strExtName;
}
void CFileUtils::GetFileList(
std::vector<_tstring>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth /* = MAX_PATH */,
bool bIgnoreCase/* = true*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
hFindHandle = FindFirstFile((strDir + _T("\\*.*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return;
}
do
{
_tstring strName = findData.cFileName;
//非目录
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
if (extList.empty())
{
fileList.emplace_back(strDir + _T("\\") + strName);
}
else
{
//获取扩展名
_tstring strExtName = GetFileExtName(strName, false);
//大小写比较区分
if (bIgnoreCase)
{
//进行扩展名过滤
for (auto& item : extList)
{
if (0 == _tcsicmp(item.c_str(), strExtName.c_str()))
{
fileList.emplace_back(strDir + _T("\\") + strName);
}
}
}
else
{
//进行扩展名过滤
for (auto& item : extList)
{
if (item == strExtName)
{
fileList.emplace_back(strDir + _T("\\") + strName);
}
}
}
}
continue;
}
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
(void)GetFileList(fileList, strDir + _T("\\") + strName, extList, depth - 1);
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
}
void CFileUtils::GetFileList(
std::set<_tstring>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList/* = {}*/,
int32_t depth/* = MAX_PATH*/,
bool bIgnoreCase/* = true*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
hFindHandle = FindFirstFile((strDir + _T("\\*.*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return;
}
do
{
_tstring strName = findData.cFileName;
//非目录
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
if (extList.empty())
{
fileList.insert(strDir + _T("\\") + strName);
}
else
{
//获取扩展名
_tstring strExtName = GetFileExtName(strName, false);
//大小写比较区分
if (bIgnoreCase)
{
//进行扩展名过滤
for (auto& item : extList)
{
if (0 == _tcsicmp(item.c_str(), strExtName.c_str()))
{
fileList.insert(strDir + _T("\\") + strName);
}
}
}
else
{
//进行扩展名过滤
for (auto& item : extList)
{
if (item == strExtName)
{
fileList.insert(strDir + _T("\\") + strName);
}
}
}
}
continue;
}
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
(void)GetFileList(fileList, strDir + _T("\\") + strName, extList, depth - 1);
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
}
void CFileUtils::GetFileList(
std::map<_tstring, FILEINFO>& fileList,
const _tstring& dir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth /* = MAX_PATH */,
bool bIgnoreCase/* = true*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
hFindHandle = FindFirstFile((dir + _T("\\*.*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return;
}
do
{
_tstring strName = findData.cFileName;
//非目录
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
FILEINFO info;
info.m_fileName = findData.cFileName;
info.m_fileSize = (unsigned long long)findData.nFileSizeHigh << 32 | findData.nFileSizeLow;
info.m_fileDir = dir;
info.m_filePath = dir + _T("\\") + strName;
info.m_ftCreationTime = *(size_t*)&findData.ftCreationTime;
info.m_ftLastAccessTime = *(size_t*)&findData.ftLastAccessTime;
info.m_ftLastWriteTime = *(size_t*)&findData.ftLastWriteTime;
info.m_fileAttributes = findData.dwFileAttributes;
info.m_ftCreationTime = (info.m_ftCreationTime - 116444736000000000) / 10000000;
info.m_ftLastAccessTime = (info.m_ftLastAccessTime - 116444736000000000) / 10000000;
info.m_ftLastWriteTime = (info.m_ftLastWriteTime - 116444736000000000) / 10000000;
if (extList.empty())
{
fileList.insert(std::make_pair(dir + _T("\\") + strName, info));
}
else
{
//获取扩展名
_tstring strExtName = GetFileExtName(strName, false);
//大小写比较区分
if (bIgnoreCase)
{
//进行扩展名过滤
for (const auto& item : extList)
{
if (0 == _tcsicmp(item.c_str(), strExtName.c_str()))
{
fileList.insert(std::make_pair(dir + _T("\\") + strName, info));
}
}
}
else
{
//进行扩展名过滤
for (const auto& item : extList)
{
if (item == strExtName)
{
fileList.insert(std::make_pair(dir + _T("\\") + strName, info));
}
}
}
}
continue;
}
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
(void)GetFileList(fileList, dir + _T("\\") + strName, extList, depth - 1);
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
}
void CFileUtils::GetDirList(
std::vector<_tstring>& fileList,
const _tstring& strDir,
int32_t depth/* = MAX_PATH*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
hFindHandle = FindFirstFile((strDir + _T("\\*.*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return;
}
do
{
_tstring strName = findData.cFileName;
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
//非目录
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
continue;
}
fileList.emplace_back(strDir + _T("\\") + strName);
(void)GetDirList(fileList, strDir + _T("\\") + strName, depth - 1);
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
}
void CFileUtils::GetDirList(
std::map<_tstring, FILEINFO>& dirList,
const _tstring& strDir,
int32_t depth/* = MAX_PATH*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
hFindHandle = FindFirstFile((strDir + _T("\\*.*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return;
}
do
{
_tstring strName = findData.cFileName;
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
//非目录
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
continue;
}
FILEINFO info;
info.m_fileName = findData.cFileName;
info.m_fileSize = (unsigned long long)findData.nFileSizeHigh << 32 | findData.nFileSizeLow;
info.m_fileDir = strDir;
info.m_filePath = strDir + _T("\\") + strName;
info.m_ftCreationTime = *(size_t*)&findData.ftCreationTime;
info.m_ftLastAccessTime = *(size_t*)&findData.ftLastAccessTime;
info.m_ftLastWriteTime = *(size_t*)&findData.ftLastWriteTime;
info.m_fileAttributes = findData.dwFileAttributes;
info.m_ftCreationTime = (info.m_ftCreationTime - 116444736000000000) / 10000000;
info.m_ftLastAccessTime = (info.m_ftLastAccessTime - 116444736000000000) / 10000000;
info.m_ftLastWriteTime = (info.m_ftLastWriteTime - 116444736000000000) / 10000000;
dirList.insert(std::make_pair(strDir + _T("\\") + strName, info));
(void)GetDirList(dirList, strDir + _T("\\") + strName, depth - 1);
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
}
bool CFileUtils::IsExist(const _tstring& strPath)
{
return 0 == _taccess_s(strPath.c_str(), 00);
}
bool CFileUtils::IsHidden(const _tstring& strPath)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
return attr.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN;
}
bool CFileUtils::IsArchive(const _tstring& strPath)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
return attr.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE;
}
bool CFileUtils::IsReadOnly(const _tstring& strPath)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
return attr.dwFileAttributes & FILE_ATTRIBUTE_READONLY;
}
bool CFileUtils::IsDirectory(const _tstring& strPath)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
return attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
}
bool CFileUtils::GetAttributes(const _tstring& strPath, DWORD& dwAttr)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
dwAttr = attr.dwFileAttributes;
return true;
}
bool CFileUtils::SetAttributes(const _tstring& strPath, const DWORD& dwAttr)
{
return ::SetFileAttributes(strPath.c_str(), dwAttr);
}
unsigned long long CFileUtils::GetFileSize(const _tstring& strPath)
{
unsigned long long ullSize = 0;
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return 0;
}
ullSize = (unsigned long long)attr.nFileSizeHigh << 32 | attr.nFileSizeLow;
return ullSize;
}
bool CFileUtils::DeleteArchive(const _tstring& strPath)
{
bool bSuccess = false;
if (strPath.empty())
{
return false;
}
bSuccess = ::DeleteFile(strPath.c_str());
if (!bSuccess && ERROR_FILE_NOT_FOUND == ::GetLastError())
{
bSuccess = true;
}
return bSuccess;
}
bool CFileUtils::DeleteDir(const _tstring& strDir)
{
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
if (strDir.empty())
{
return false;
}
hFindHandle = FindFirstFile((strDir + _T("\\*.*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return false;
}
do
{
_tstring strFilePath = strDir + _T("\\") + findData.cFileName;
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //删除目录
{
DeleteDir(strFilePath);
continue;
}
else //删除文件
{
::DeleteFile(strFilePath.c_str());
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
return ::RemoveDirectory(strDir.c_str());
}
bool CFileUtils::CreateDir(const _tstring& strPath)
{
_tstring strDriver; //驱动器号, 如 D:
_tstring strSubPath = strPath; //路径, 如 Test\1\2\3
if (strPath.empty())
{
return false;
}
//获取盘符
do
{
size_t nFindIndex = strPath.find_first_of(':'); //检查是否有驱动器号
if (nFindIndex == _tstring::npos)
{
break;
}
strDriver = strPath.substr(0, nFindIndex + 1); //得到驱动器号, 如 D:
nFindIndex = strPath.find(_T("\\"), nFindIndex);
if (nFindIndex == _tstring::npos)
{
break;
}
strSubPath = strPath.substr(nFindIndex + 1); //得到路径, 如 Test\1\2\3
} while (false);
_tstring strDestDir;
size_t nFindBegin = 0;
size_t nFindIndex = 0;
do
{
nFindIndex = strSubPath.find(_T("\\"), nFindBegin);
if (nFindIndex != _tstring::npos)
{
strDestDir = strSubPath.substr(0, nFindIndex);
nFindBegin = nFindIndex + 1;
}
else
{
strDestDir = strSubPath;
}
if (!strDriver.empty())
{
strDestDir = strDriver + _T("\\") + strDestDir;
}
if (!::CreateDirectory(strDestDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != ::GetLastError())
{
return false;
}
}while (nFindIndex != _tstring::npos);
return true;
}
CFileHelper::CFileHelper()
:
m_hFile(INVALID_HANDLE_VALUE)
{
}
CFileHelper::CFileHelper(const _tstring& strPath, bool bReadonly/* = false*/)
{
Open(strPath, true, bReadonly);
}
CFileHelper::~CFileHelper()
{
Close();
}
bool CFileHelper::IsOpen() const
{
return INVALID_HANDLE_VALUE != m_hFile;
}
bool CFileHelper::GetSize(unsigned long long& ullSize) const
{
if (!IsOpen())
{
return false;
}
LARGE_INTEGER ullFileSize = { 0 };
if (!::GetFileSizeEx(m_hFile, &ullFileSize))
{
return false;
}
ullSize = ullFileSize.QuadPart;
return true;
}
bool CFileHelper::GetAttributes(const _tstring& strPath, DWORD& dwAttr)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
dwAttr = attr.dwFileAttributes;
return true;
}
bool CFileHelper::SetAttributes(const _tstring& strPath, const DWORD& dwAttr)
{
return ::SetFileAttributes(strPath.c_str(), dwAttr);
}
bool CFileHelper::GetAttributes(DWORD& dwAttr) const
{
if (!IsOpen())
{
return false;
}
return GetAttributes(m_strFile, dwAttr);
}
bool CFileHelper::SetAttributes(const DWORD& dwAttr) const
{
if (!IsOpen())
{
return false;
}
return SetAttributes(m_strFile, dwAttr);
}
bool CFileHelper::Open(const _tstring& strPath, bool bCreateIfNoExist/* = false*/, bool bReadonly/* = false*/)
{
if (strPath.empty())
{
return false;
}
//不重复打开相同文件
if (m_strFile == strPath && IsOpen())
{
return true;
}
//关闭文件, 如果已经打开
Close();
m_strFile = strPath;
DWORD dwOpenFlag = GENERIC_READ;
if (!bReadonly)
{
dwOpenFlag |= GENERIC_WRITE;
}
m_hFile = CreateFile(m_strFile.c_str(),
dwOpenFlag,
FILE_SHARE_READ,
NULL,
bCreateIfNoExist ? OPEN_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == m_hFile)
{
return false;
}
return true;
}
void CFileHelper::Close()
{
if (INVALID_HANDLE_VALUE != m_hFile)
{
::CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
}
LONGLONG CFileHelper::GetPointer() const
{
LARGE_INTEGER liDistanceToMove = { 0 };
LARGE_INTEGER liNewFilePointer = { 0 };
::SetFilePointerEx(m_hFile, liDistanceToMove, &liNewFilePointer, FILE_CURRENT);
return liNewFilePointer.QuadPart;
}
bool CFileHelper::SetPointer(LONGLONG llPos/* = 0*/, DWORD dwFlag/* = FILE_CURRENT*/)
{
LARGE_INTEGER liDistanceToMove = { 0 };
if (!IsOpen())
{
return false;
}
liDistanceToMove.QuadPart = llPos;
return ::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, dwFlag);
}
bool CFileHelper::Read(LPVOID lpBuffer, DWORD dwSize, LONGLONG llPos/* = 0*/, LPDWORD lpBytesRead/* = nullptr*/, DWORD dwFlag/* = FILE_CURRENT*/)
{
if (!IsOpen() || nullptr == lpBuffer)
{
return false;
}
LARGE_INTEGER liDistanceToMove = { 0 };
BOOL bResult = FALSE;
liDistanceToMove.QuadPart = llPos;
::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, dwFlag);
DWORD dwBytesRead = 0;
bResult = ::ReadFile(m_hFile, lpBuffer, dwSize, &dwBytesRead, NULL);
if (nullptr != lpBytesRead)
{
*lpBytesRead = dwBytesRead;
}
return bResult;
}
bool CFileHelper::Write(LPCVOID lpBuffer, DWORD dwSize, LONGLONG llPos/* = 0*/, LPDWORD lpBytesWritten/* = nullptr*/, DWORD dwFlag/* = FILE_CURRENT*/)
{
if (!IsOpen() || nullptr == lpBuffer)
{
return false;
}
LARGE_INTEGER liDistanceToMove = { 0 };
BOOL bResult = FALSE;
liDistanceToMove.QuadPart = llPos;
::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, dwFlag);
DWORD dwBytesWritten = 0;
bResult = ::WriteFile(m_hFile, lpBuffer, dwSize, &dwBytesWritten, NULL);
if (nullptr != lpBytesWritten)
{
*lpBytesWritten = dwBytesWritten;
}
return bResult;
}
bool CFileHelper::Clear()
{
if (!IsOpen())
{
return false;
}
LARGE_INTEGER liDistanceToMove = { 0 };
::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, FILE_BEGIN);
return ::SetEndOfFile(m_hFile);
}
bool CFileHelper::SetEnd(LONGLONG llPos)
{
if (!IsOpen())
{
return false;
}
LARGE_INTEGER liDistanceToMove = { 0 };
liDistanceToMove.QuadPart = llPos;
::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, FILE_BEGIN);
return ::SetEndOfFile(m_hFile);
}