filemisc.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 777 行 · 第 1/2 页
CPP
777 行
#include "stdafx.h"
#include "filemisc.h"
#include "misc.h"
#include <sys/utime.h>
#include <sys/stat.h>
#include <direct.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
CFileBackup::CFileBackup(const CString& sFile, const CString& sExt)
{
MakeBackup(sFile, sExt);
}
CFileBackup::~CFileBackup()
{
if (FileMisc::FileExists(m_sBackup))
::DeleteFile(m_sBackup);
}
BOOL CFileBackup::MakeBackup(const CString& sFile, const CString& sExt)
{
ASSERT (m_sFile.IsEmpty() && m_sBackup.IsEmpty());
if (!m_sFile.IsEmpty() || !m_sBackup.IsEmpty())
return FALSE;
if (!FileMisc::FileExists(sFile))
return FALSE;
m_sFile = sFile;
m_sBackup = BuildBackupPath(sFile, sExt);
return ::CopyFile(m_sFile, m_sBackup, FALSE);
}
BOOL CFileBackup::RestoreBackup()
{
ASSERT (!m_sFile.IsEmpty() && !m_sBackup.IsEmpty());
if (m_sFile.IsEmpty() || m_sBackup.IsEmpty())
return FALSE;
return ::CopyFile(m_sBackup, m_sFile, FALSE);
}
CString CFileBackup::BuildBackupPath(const CString& sFile, const CString& sExt)
{
CString sBackup(sFile);
sBackup.TrimRight();
// add extension
if (sExt.IsEmpty())
sBackup += ".bak";
else
{
if (sExt.Find('.') == -1)
sBackup += '.';
sBackup += sExt;
}
return sBackup;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void FileMisc::TerminatePath(CString& sPath)
{
sPath.TrimRight();
if (sPath.ReverseFind('\\') != (sPath.GetLength() - 1))
sPath += '\\';
}
void FileMisc::UnterminatePath(CString& sPath)
{
sPath.TrimRight();
int len = sPath.GetLength();
if (sPath.ReverseFind('\\') == (len - 1))
sPath = sPath.Left(len - 1);
}
void FileMisc::ReplaceExtension(CString& sFilePath, const char* szExt)
{
CString sDrive, sDir, sFile;
SplitPath(sFilePath, &sDrive, &sDir, &sFile);
MakePath(sFilePath, sDrive, sDir, sFile, szExt);
}
CString& FileMisc::ValidateFilepath(CString& sFilepath)
{
sFilepath.TrimLeft();
sFilepath.TrimRight();
sFilepath.Replace("/", "");
sFilepath.Replace("*", "");
sFilepath.Replace("?", "");
sFilepath.Replace("\"", "");
sFilepath.Replace("<", "");
sFilepath.Replace(">", "");
sFilepath.Replace("|", "");
// make sure if a colon exists it is the 2nd pos
int nColon = sFilepath.Find(':');
while (nColon != -1 && nColon != 1)
{
// delete the colon
sFilepath = sFilepath.Left(nColon) + sFilepath.Mid(nColon + 1);
nColon = sFilepath.Find(':', nColon);
}
return sFilepath;
}
CString& FileMisc::ValidateFilename(CString& sFilename)
{
sFilename.Replace("\\", "");
sFilename.Replace(":", "");
return ValidateFilepath(sFilename);
}
const char* FileMisc::GetFileNameFromPath(const char* szFilepath)
{
const char* szFilename = strrchr(szFilepath, '\\');
if (szFilename)
return szFilename + 1;
// else
return szFilepath;
}
time_t FileMisc::GetLastModified(const char* szPath)
{
struct _stat st;
if (!szPath || _stat(szPath, &st) != 0)
return 0;
// files only
if ((st.st_mode & _S_IFDIR) == _S_IFDIR)
return 0;
return st.st_mtime;
}
bool FileMisc::GetLastModified(const char* szPath, SYSTEMTIME& sysTime, bool bLocalTime)
{
ZeroMemory(&sysTime, sizeof(SYSTEMTIME));
DWORD dwAttr = ::GetFileAttributes(szPath);
// files only
if (dwAttr == 0xFFFFFFFF)
return false;
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((LPTSTR)szPath, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
return FALSE;
FindClose(hFind);
FILETIME ft = findFileData.ftLastWriteTime;
if (bLocalTime)
FileTimeToLocalFileTime(&findFileData.ftLastWriteTime, &ft);
FileTimeToSystemTime(&ft, &sysTime);
return true;
}
bool FileMisc::ResetLastModified(const char* szPath)
{
::SetFileAttributes(szPath, FILE_ATTRIBUTE_NORMAL);
return (_utime(szPath, NULL) == 0);
}
bool FileMisc::DeleteFolderContents(const char* szFolder, BOOL bIncludeSubFolders, const char* szFileMask, HANDLE hTerminate, BOOL bProcessMsgLoop)
{
// if the dir does not exists just return
if (!FolderExists(szFolder))
return true;
// if a file mask has been specified with subfolders we need to do 2 passes on each folder,
// one for the files and one for the sub folders
int nPasses = (bIncludeSubFolders && (szFileMask && lstrlen(szFileMask))) ? 2 : 1;
bool bResult = true;
bool bStopped = (WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0);
for (int nPass = 0; !bStopped && nPass < nPasses; nPass++)
{
CString sSearchSpec(szFolder), sMask(szFileMask);
if (sMask.IsEmpty() || nPass == 1) // (nPass == 1) == 2nd pass (for folders)
sMask = "*.*";
TerminatePath(sSearchSpec);
sSearchSpec += sMask;
WIN32_FIND_DATA finfo;
HANDLE hSearch = NULL;
if ((hSearch = FindFirstFile(sSearchSpec, &finfo)) != INVALID_HANDLE_VALUE)
{
do
{
if (bProcessMsgLoop)
Misc::ProcessMsgLoop();
if (finfo.cFileName[0] != '.')
{
CString sItem(szFolder);
sItem += "\\";
sItem += finfo.cFileName;
if (finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (bIncludeSubFolders && (nPass == 1 || nPasses == 1))
{
if (DeleteFolderContents(sItem, TRUE, szFileMask, hTerminate, bProcessMsgLoop))
{
if (!szFileMask || !lstrlen(szFileMask))
bResult = (RemoveDirectory(sItem) == TRUE);
}
}
}
else
bResult = (DeleteFile(sItem) == TRUE);
}
bStopped = (WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0);
}
while (!bStopped && bResult && FindNextFile(hSearch, &finfo));
FindClose(hSearch);
}
}
return (!bStopped && bResult);
}
bool FileMisc::RemoveFolder(const char* szFolder, HANDLE hTerminate, BOOL bProcessMsgLoop)
{
// if the dir does not exists just return
if (!FolderExists(szFolder))
return true;
if (DeleteFolderContents(szFolder, TRUE, NULL, hTerminate, bProcessMsgLoop))
{
::SetFileAttributes(szFolder, FILE_ATTRIBUTE_NORMAL);
return (RemoveDirectory(szFolder) == TRUE);
}
return false;
}
double FileMisc::GetFolderSize(const char* szFolder, BOOL bIncludeSubFolders, const char* szFileMask, HANDLE hTerminate, BOOL bProcessMsgLoop)
{
// if the dir does not exists just return
if (!FolderExists(szFolder))
return 0;
double dSize = 0;
WIN32_FIND_DATA finfo;
CString sSearchSpec(szFolder), sFileMask(szFileMask);
if (sFileMask.IsEmpty())
sFileMask = "*.*";
TerminatePath(sSearchSpec);
sSearchSpec += sFileMask;
BOOL bStopped = (WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0);
HANDLE h = NULL;
if (!bStopped && (h = FindFirstFile(sSearchSpec, &finfo)) != INVALID_HANDLE_VALUE)
{
do
{
if (bProcessMsgLoop)
Misc::ProcessMsgLoop();
if (finfo.cFileName[0] != '.')
{
if (finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (bIncludeSubFolders)
{
CString sSubFolder(szFolder);
sSubFolder += "\\";
sSubFolder += finfo.cFileName;
dSize += GetFolderSize(sSubFolder, TRUE, sFileMask, hTerminate, bProcessMsgLoop);
}
}
else
dSize += (finfo.nFileSizeHigh * ((double)MAXDWORD + 1)) + finfo.nFileSizeLow;
}
bStopped = (WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0);
}
while (!bStopped && FindNextFile(h, &finfo));
FindClose(h);
}
return bStopped ? -1 : dSize;
}
bool FileMisc::FolderExists(const char* szFolder)
{
DWORD dwAttrib = GetFileAttributes(szFolder);
return (dwAttrib != 0xffffffff && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
bool FileMisc::FileExists(const char* szFile)
{
DWORD dwAttrib = GetFileAttributes(szFile);
return (dwAttrib != 0xffffffff && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == 0);
}
bool FileMisc::FolderFromFilePathExists(const char* szFilePath)
{
return FolderExists(GetFolderFromFilePath(szFilePath));
}
CString FileMisc::GetCwd()
{
char szCwd[MAX_PATH];
GetCurrentDirectory(MAX_PATH, szCwd);
return szCwd;
}
CString FileMisc::GetFolderFromFilePath(const char* szFilePath)
{
CString sFolder;
// check if its a folder already
if (FolderExists(szFilePath))
{
sFolder = szFilePath;
}
else
{
// remove file ending
CString sDrive, sDir;
SplitPath(szFilePath, &sDrive, &sDir);
MakePath(sFolder, sDrive, sDir);
}
return sFolder;
}
bool FileMisc::CreateFolderFromFilePath(const char* szFilePath)
{
return CreateFolder(GetFolderFromFilePath(szFilePath));
}
bool FileMisc::PathHasWildcard(const char* szFilePath)
{
return (strchr(szFilePath, '?') || strchr(szFilePath, '*'));
}
bool FileMisc::CreateFolder(const char* szFolder)
{
if (FolderExists(szFolder))
return true;
// start from the highest level folder working to the lowest
CString sFolder, sRemaining(szFolder);
UnterminatePath(sRemaining);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?