// Copyright (c) 2020 Lv Decai, Shenzhen, China.// Filename: FileUtility.cpp// Version: 1.0// Release date: 2020年10月11日// License: MIT (http://opensource.org/licenses/MIT)#include "StdAfx.h"#include <ShlObj.h>#include "Buffer.h"#include "DllLoader.h"#include "FileUtility.h"#include "StringUtility.h"#pragma comment(lib, "Version.lib")NAMESPACE_BEGIN;// 判断目录是否存在BOOL FileUtility::DirectoryExists(PCTSTR sPath){if (!StringUtility::ValidString(sPath)){return FALSE;}CString sDirectory(sPath);if (sDirectory.GetLength() == 2 && sDirectory[1] == _T(':')){// 单独的盘符要转换为根目录sDirectory += _T('\\');}else{// 其他路径,要去掉末尾的反斜线,否则 FindFirstFile 查找的将是目录下的子目录,而不是目录本身sDirectory.TrimRight(_T('\\'));}WIN32_FIND_DATA Win32FindData = { 0 };HANDLE hFindFile = FindFirstFile(sDirectory, &Win32FindData);if (hFindFile == INVALID_HANDLE_VALUE){return FALSE;}FindClose(hFindFile);return Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;}// 判断文件是否存在BOOL FileUtility::FileExists(PCTSTR sPath){if (!StringUtility::ValidString(sPath)){return FALSE;}WIN32_FIND_DATA Win32FindData = { 0 };HANDLE hFindFile = FindFirstFile(sPath, &Win32FindData);if (hFindFile == INVALID_HANDLE_VALUE){return FALSE;}FindClose(hFindFile);return (Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;}// 从文件全路径截取目录CString FileUtility::ExtractDirectory(PCTSTR sPath, BOOL bEndWithBackSlash){CString sPathCopy(sPath);int iPos = sPathCopy.ReverseFind(_T('\\'));if (iPos != -1){sPathCopy = sPathCopy.Left(bEndWithBackSlash ? iPos + 1 : iPos);}else{iPos = sPathCopy.ReverseFind(_T('/'));if (iPos != -1){sPathCopy = sPathCopy.Left(bEndWithBackSlash ? iPos + 1 : iPos);}else{sPathCopy.Empty();}}return sPathCopy;}// 从文件全路径截取文件名CString FileUtility::ExtractFilename(PCTSTR sPath, BOOL bIncludeExt){CString sPathCopy = sPath;int iPos = sPathCopy.ReverseFind(_T('\\'));if (iPos != -1){sPathCopy = sPathCopy.Mid(iPos + 1);}else{iPos = sPathCopy.ReverseFind(_T('/'));if (iPos != -1){sPathCopy = sPathCopy.Mid(iPos + 1);}}if (!bIncludeExt){iPos = sPathCopy.ReverseFind(_T('.'));if (iPos != -1){sPathCopy = sPathCopy.Left(iPos);}}return sPathCopy;}// 从文件名截取扩展名,不含 . 字符CString FileUtility::ExtractFileExt(PCTSTR sPath){CString sPathCopy = sPath;int iPos = sPathCopy.ReverseFind(_T('.'));if (iPos == -1){sPathCopy.Empty();}else{sPathCopy = sPathCopy.Mid(iPos + 1);}return sPathCopy;}// 递归创建目录BOOL FileUtility::CreateDirectoryRecursively(PCTSTR sDirectory){if (!StringUtility::ValidString(sDirectory)){return FALSE;}if (DirectoryExists(sDirectory)){return TRUE;}CString sParentDirectory = ExtractDirectory(sDirectory, FALSE);if (!CreateDirectoryRecursively(sParentDirectory)){return FALSE;}return CreateDirectory(sDirectory, NULL);}// 删除目录及目录中的子目录和文件BOOL FileUtility::DeleteDirectory(PCTSTR sDirectory){if (!StringUtility::ValidString(sDirectory)){return FALSE;}CString sDirectoryCopy(sDirectory);sDirectoryCopy.TrimRight(_T('\\'));CFileStatus FileStatus;// 检查状态if (!CFile::GetStatus(sDirectoryCopy, FileStatus)){return FALSE;}// 检查属性if ((FileStatus.m_attribute & CFile::directory) == 0){return FALSE;}// 遍历目录下的子目录和文件CFileFind FileFind;BOOL bContinue = FileFind.FindFile(sDirectoryCopy + _T("\\*.*"));while (bContinue){bContinue = FileFind.FindNextFile();if (FileFind.IsDots()){continue;}else if (FileFind.IsDirectory()){// 递归删除子目录if (!DeleteDirectory(FileFind.GetFilePath())){return FALSE;}}else{// 去除文件的只读、系统、隐藏属性RemoveFileAttribute(FileFind.GetFilePath(),FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);// 删除文件if (!DeleteFile(FileFind.GetFilePath())){return FALSE;}}}// 关闭打开的目录项FileFind.Close();// 去除目录的只读、系统、隐藏属性RemoveFileAttribute(sDirectoryCopy, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);// 删除空目录return RemoveDirectory(sDirectoryCopy);}// 删除指定目录下匹配模式的所有文件BOOL FileUtility::DeleteFiles(PCTSTR sDirectory, PCTSTR sPattern, BOOL bRecursively){if (!StringUtility::ValidString(sDirectory)){return FALSE;}// 取得文件列表list<CString> lstFile;GetFileList(lstFile, sDirectory, sPattern, bRecursively);for (CString& sFilePath : lstFile){// 去除文件的只读、系统、隐藏属性RemoveFileAttribute(sFilePath, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);// 删除文件if (!DeleteFile(sFilePath)){return FALSE;}}return TRUE;}// 添加文件属性BOOL FileUtility::AddFileAttribute(PCTSTR sPath, int iAttributes){DWORD iCurrentAttributes = GetFileAttributes(sPath);if ((iCurrentAttributes & iAttributes) != 0){return SetFileAttributes(sPath, iCurrentAttributes & ~iAttributes);}return FALSE;}// 移除文件属性BOOL FileUtility::RemoveFileAttribute(PCTSTR sPath, int iAttributes){return AddFileAttribute(sPath, ~iAttributes);}// 获取文件大小ULONGLONG FileUtility::GetFileSize(PCTSTR sPath){CFileStatus FileStatus;if (CFile::GetStatus(sPath, FileStatus)){return FileStatus.m_size;}return 0;}// 获取文件版本号FileUtility::CFileVersion FileUtility::GetFileVersion(PCTSTR sPath){CFileVersion FileVersion;DWORD iVersionInfoSize = 0;iVersionInfoSize = GetFileVersionInfoSize(sPath, &iVersionInfoSize);if (iVersionInfoSize == 0){return FileVersion;}CBuffer Buffer;Buffer.Resize(iVersionInfoSize * sizeof(TCHAR));TCHAR* pBuffer = (TCHAR*) Buffer.Get();if (!GetFileVersionInfo(sPath, 0, iVersionInfoSize, pBuffer)){return FileVersion;}PDWORD pLanguage = NULL;UINT iDataLength = 0;if (!VerQueryValue(pBuffer, _T("\\VarFileInfo\\Translation"), (PVOID*) &pLanguage, &iDataLength)){return FileVersion;}FileVersion.Language.Format(_T("%04x%04x"), LOWORD(*pLanguage), HIWORD(*pLanguage));CString sKeyPrefix = _T("\\StringFileInfo\\") + FileVersion.Language + _T("\\");PCTSTR pString = NULL;// 出品公司if (VerQueryValue(pBuffer, sKeyPrefix + _T("CompanyName"), (PVOID*) &pString, &iDataLength)){FileVersion.CompanyName = pString;}// 文件描述if (VerQueryValue(pBuffer, sKeyPrefix + _T("FileDescription"), (PVOID*) &pString, &iDataLength)){FileVersion.FileDescription = pString;}// 文件版本if (VerQueryValue(pBuffer, sKeyPrefix + _T("FileVersion"), (PVOID*) &pString, &iDataLength)){FileVersion.FileVersion = pString;}// 内部名称if (VerQueryValue(pBuffer, sKeyPrefix + _T("InternalName"), (PVOID*) &pString, &iDataLength)){FileVersion.InternalName = pString;}// 合法版权if (VerQueryValue(pBuffer, sKeyPrefix + _T("LegalCopyright"), (PVOID*) &pString, &iDataLength)){FileVersion.LegalCopyright = pString;}// 原名称if (VerQueryValue(pBuffer, sKeyPrefix + _T("OriginalFilename"), (PVOID*) &pString, &iDataLength)){FileVersion.OriginalFilename = pString;}// 产品名称if (VerQueryValue(pBuffer, sKeyPrefix + _T("ProductName"), (PVOID*) &pString, &iDataLength)){FileVersion.ProductName = pString;}// 产品版本if (VerQueryValue(pBuffer, sKeyPrefix + _T("ProductVersion"), (PVOID*) &pString, &iDataLength)){FileVersion.ProductVersion = pString;}return FileVersion;}// 获取模块文件路径// hModule - 打开的模块句柄,NULL 表示获取可执行文件名路径CString FileUtility::GetModulePath(HMODULE hModule){TCHAR sModuleFileName[MAX_PATH] = { 0 };GetModuleFileName(hModule, sModuleFileName, MAX_PATH);return sModuleFileName;}// 获取应用程序可执行文件名,不含目录CString FileUtility::GetAppName(BOOL bIncludeExt){const CString& sAppExePath = GetModulePath(NULL);return ExtractFilename(sAppExePath, bIncludeExt);}// 获取模块文件所在目录CString FileUtility::GetModuleDirectory(HMODULE hModule, BOOL bEndWithBackSlash){return ExtractDirectory(GetModulePath(hModule), bEndWithBackSlash);}// 获取应用程序可执行文件所在目录CString FileUtility::GetAppDirectory(BOOL bEndWithBackSlash){return GetModuleDirectory(NULL, bEndWithBackSlash);}// 获取特殊目录CString FileUtility::GetSpecialDirectory(int iType, BOOL bEndWithBackSlash){TCHAR sDirectory[MAX_PATH] = { 0 };SHGetSpecialFolderPath(NULL, sDirectory, iType, FALSE);if (bEndWithBackSlash){_tcscat(sDirectory, _T("\\"));}return sDirectory;}// 在指定目录及其各级父目录下查找文件,返回存在的最长的文件路径// 返回值:如果找到文件,返回存在的最长的文件路径,否则返回空字符串CString FileUtility::FindFile(CString sSearchDirectory, CString sRelativeFilePath){sSearchDirectory.TrimRight(_T("\\"));while (!sSearchDirectory.IsEmpty()){CString sFilePath = sSearchDirectory + _T("\\") + sRelativeFilePath;if (FileUtility::FileExists(sFilePath)){return sFilePath;}sSearchDirectory = FileUtility::ExtractDirectory(sSearchDirectory, FALSE);}return _T("");}// 在 Path 环境变量的各个目录下查找文件// 返回值:如果找到文件,返回第一存在的文件路径,否则返回空字符串CString FileUtility::FindFileInPathEnvironment(PCTSTR sRelativeFilePath){CString sPathList = StringUtility::GetEnvironmentVariable(_T("Path"));list<CString> lstPath;StringUtility::Split(sPathList, lstPath, _T(";"));for (CString& sDirectory : lstPath){CString sFilePath;if (sDirectory.Right(1) == _T("\\")){sFilePath = sDirectory + sRelativeFilePath;}else{sFilePath = sDirectory + _T("\\") + sRelativeFilePath;}if (FileExists(sFilePath)){return sFilePath;}}return _T("");}// 把目录添加到 Path 环境变量中BOOL FileUtility::AddDirectoryToPathEnvironment(PCTSTR sDirectory){CString sPathList = StringUtility::GetEnvironmentVariable(_T("Path"));list<CString> lstPath;StringUtility::Split((PCTSTR) sPathList, lstPath, _T(";"));if (find(lstPath.begin(), lstPath.end(), sDirectory) == lstPath.end()){return StringUtility::SetEnvironmentVariable(_T("Path"), sPathList + _T(";") + sDirectory);}return FALSE;}// 把目录批量添加到 Path 环境变量中BOOL FileUtility::AddDirectoryToPathEnvironment(const list<CString>& lstDirectory){CString sPathList = StringUtility::GetEnvironmentVariable(_T("Path"));list<CString> lstPath;StringUtility::Split(sPathList, lstPath, _T(";"));CString sAppendString;for (auto& sDirectory : lstDirectory){if (find(lstPath.begin(), lstPath.end(), sDirectory) == lstPath.end()){sAppendString += _T(";") + sDirectory;}}if (!sAppendString.IsEmpty()){return StringUtility::SetEnvironmentVariable(_T("Path"), sPathList + sAppendString);}return FALSE;}// 获取指定目录下的文件列表void FileUtility::GetFileList(list<CString>& lstFile, PCTSTR sDirectory, PCTSTR sPattern, BOOL bRecursively){if (!DirectoryExists(sDirectory)){return;}CString sDirectoryCopy(sDirectory);if (sDirectoryCopy.Right(1) != _T("\\")){sDirectoryCopy += _T("\\");}CFileFind FileFind;BOOL bContinue = FileFind.FindFile(sDirectoryCopy + sPattern);while (bContinue){bContinue = FileFind.FindNextFile();if (!FileFind.IsDirectory()){lstFile.push_back(FileFind.GetFilePath());}}if (bRecursively){FileFind.Close();bContinue = FileFind.FindFile(sDirectoryCopy + _T("*.*"));while (bContinue){bContinue = FileFind.FindNextFile();if (FileFind.IsDirectory() && !FileFind.IsDots()){GetFileList(lstFile, FileFind.GetFilePath(), sPattern, bRecursively);}}}}// 比较两个文件的修改时间,如果相等返回 0,如果文件 1 早于文件 2 返回 -1,如果文件 1 晚于文件 2 返回 1int FileUtility::CompareFileModificationTime(PCTSTR sFilePath1, PCTSTR sFilePath2){CFileStatus FileStatus1;CFileStatus FileStatus2;if (CFile::GetStatus(sFilePath1, FileStatus1)){if (CFile::GetStatus(sFilePath2, FileStatus2)){if (FileStatus1.m_mtime < FileStatus2.m_mtime){return -1;}else if (FileStatus1.m_mtime == FileStatus2.m_mtime){return 0;}else{return 1;}}else{return 1;}}else if (CFile::GetStatus(sFilePath2, FileStatus2)){return -1;}else{return 0;}}// 注册 COMBOOL FileUtility::RegisterCom(PCTSTR sPath){CDllLoader DllLoader(sPath);if (!DllLoader.IsValid()){return FALSE;}FARPROC DllRegisterServer = DllLoader.GetProc("DllRegisterServer");if (DllRegisterServer == NULL){return FALSE;}try{return SUCCEEDED(DllRegisterServer());}catch (...){return FALSE;}}// 反注册 COMBOOL FileUtility::UnregisterCom(PCTSTR sPath){CDllLoader DllLoader(sPath);if (!DllLoader.IsValid()){return FALSE;}FARPROC DllUnregisterServer = DllLoader.GetProc("DllUnregisterServer");if (DllUnregisterServer == NULL){return FALSE;}try{return SUCCEEDED(DllUnregisterServer());}catch (...){return FALSE;}}// 从文件读取内容到缓冲区BOOL FileUtility::ReadFileContent(PCTSTR sPath, void* pBuffer, UINT iBufferSize){if (!StringUtility::ValidString(sPath)|| pBuffer == NULL|| iBufferSize == 0){return FALSE;}try{CFile File(sPath, CFile::modeRead);UINT iFileSize = (UINT) File.GetLength();if (iFileSize > iBufferSize){iFileSize = iBufferSize;}File.Read(pBuffer, iFileSize);return TRUE;}catch (CFileException* e){e->Delete();}return FALSE;}// 把缓冲区中的内容写入文件BOOL FileUtility::WriteFileContent(PCTSTR sPath, PCVOID pBuffer, UINT iBufferSize){if (!StringUtility::ValidString(sPath)|| pBuffer == NULL|| iBufferSize == 0){return FALSE;}try{CFile File(sPath, CFile::modeCreate + CFile::modeWrite);File.Write(pBuffer, iBufferSize);return TRUE;}catch (CFileException* e){e->Delete();}return FALSE;}// 从文件读取内容BOOL FileUtility::ReadFileContent(PCTSTR sPath, string& sContent){try{CFile File(sPath, CFile::modeRead);UINT iFileSize = (UINT) File.GetLength();sContent.resize(iFileSize);File.Read((void*)sContent.data(), iFileSize);return TRUE;}catch (CFileException* e){e->Delete();}return FALSE;}// 向文件写入内容BOOL FileUtility::WriteFileContent(PCTSTR sPath, const string& sContent){if (!StringUtility::ValidString(sPath)|| sContent.empty()){return FALSE;}try{CFile File(sPath, CFile::modeCreate + CFile::modeWrite);File.Write(sContent.c_str(), (UINT)sContent.size());return TRUE;}catch (CFileException* e){e->Delete();}return FALSE;}// 向文件尾部追加内容BOOL FileUtility::AppendFileContent(PCTSTR sPath, PCVOID pContent, UINT iSize){if (!StringUtility::ValidString(sPath)|| pContent == NULL|| iSize == 0){return FALSE;}try{CFile File(sPath, CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate);File.SeekToEnd();File.Write(pContent, iSize);return TRUE;}catch (CFileException* e){e->Delete();}return FALSE;}// 拷贝文件夹内的文件及其子文件夹到目标文件夹BOOL FileUtility::CopyDirectory(CString sSrcDirectory, CString sDestDirectory){sSrcDirectory.TrimRight(_T("\\"));if (!DirectoryExists(sSrcDirectory)){return FALSE;}if (!DirectoryExists(sDestDirectory)){CreateDirectoryRecursively(sDestDirectory);}if (sDestDirectory.Right(1) != _T("\\")){sDestDirectory += _T("\\");}CFileFind FileFind;BOOL bContinue = FileFind.FindFile(sSrcDirectory + _T("\\*.*"));while (bContinue){bContinue = FileFind.FindNextFile();if (FileFind.IsDirectory()){if (!FileFind.IsDots()){// 递归复制子目录CopyDirectory(FileFind.GetFilePath(), sDestDirectory + FileFind.GetFileName());}}else{// 复制文件CopyFile(FileFind.GetFilePath(), sDestDirectory + FileFind.GetFileName(), FALSE);}}return TRUE;}NAMESPACE_END;
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。