这里记一下,免得要用的时候,东找西找。
FireDirHelper.h
#pragma once
#include <set>
namespace kagula
{
void CopyDirTree(CString srcDir,CString dstDir,std::set<CString> setExclude);
}
FireDirHelper.cpp
#include "stdafx.h"
#include <afx.h>
#include <io.h>
#include "FileDirHelper.h"
namespace kagula
{
/*
测试用例列表:
[1]源目录不存在
[2]目录名称不规范
[3]参数都是合法的
*/
BOOL IsDirectoryExist(CString dirName)
{
if(_waccess(dirName.GetBuffer(MAX_PATH), 0) == -1)
return FALSE;
return TRUE;
}
BOOL IfDirIsNoExistCreateIt(CString dstDir)
{
// 为 -1 则说明不存在,为其它则说明存在
if(_waccess(dstDir.GetBuffer(MAX_PATH), 0) == -1)
{
SECURITY_ATTRIBUTES attrDir;
SECURITY_DESCRIPTOR SecurityDescriptor;
InitializeSecurityDescriptor(&SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION);
attrDir.nLength = sizeof(SECURITY_ATTRIBUTES);
attrDir.bInheritHandle = TRUE;
attrDir.lpSecurityDescriptor = &SecurityDescriptor;
//如果目录不存在则创建一个新的目录
if( CreateDirectory(dstDir.GetBuffer(MAX_PATH),&attrDir) == 0 )
return FALSE;
}
return TRUE;;
}
CString GetLastDirName(CString dirName)
{
int nIndex = dirName.ReverseFind( '\\' );
CString subDirName;
if (nIndex>0)
{
if (nIndex < dirName.GetLength())
{
subDirName = dirName.Mid(nIndex+1);
}
}
return subDirName;
}
void FormatPathName(CString &path)
{
path.Replace(L'/',L'\\');
if ( path.GetLength()>0 && (path.GetAt(path.GetLength()-1)==L'/' || path.GetAt(path.GetLength()-1)==L'\\') )
{
path = path.Left(path.GetLength()-1);
}//end if
}
CString GetLastFileName(CString path)
{
int nIndex = path.ReverseFind( '\\' );
CString cstrResult;
if (nIndex>=0)
{
if (path.GetLength()-nIndex-1>0)
{
cstrResult = path.Mid(nIndex+1, path.GetLength()-nIndex-1);
}//end if
}//end if
return cstrResult;
}//end func
/*
example;
srcDir = L"c:\\srcDir", dstDir = L"c:\\dstDir"
setExclude={"bad0.txt","bad1.txt"}
*/
void CopyDirTree(CString srcDir,CString dstDir,std::set<CString> setExclude)
{
CFileFind finder;
//规范目录名称[1]目录名分隔符用"\\"[2]目录名的最后一个字符不是"\\"
FormatPathName(srcDir);
FormatPathName(dstDir);
//源文件夹是否存在,若不存在,则返回!
if (FALSE == IsDirectoryExist(srcDir))
{
return;
}
srcDir.Append(L"\\*.*");
//若目标目录不存在,新建它
IfDirIsNoExistCreateIt(dstDir);
//for search
BOOL hasNext = finder.FindFile(srcDir);
while (hasNext)
{
hasNext = finder.FindNextFile();
if (finder.IsDots())
continue;
if (finder.IsDirectory())
{
//取当前目录名(最下级的)
CString srcDirParam = finder.GetFilePath();
CString lastDirName = GetLastDirName(srcDirParam);
//为dstDir添加(下级)目录名
CString dstDirParam = dstDir;
dstDirParam.Append(L"\\");
dstDirParam.Append(lastDirName);
//do recursive
CopyDirTree(srcDirParam,dstDirParam,setExclude);
}
else
{
//取(不含path的)文件名
CString fileName = GetLastFileName(finder.GetFilePath());
//若这个文件在setExclude里,continue!
if (setExclude.count(fileName)>0)
{
continue;
}
//否则,复制文件到目标
CString dstFullPath = dstDir;
dstFullPath.Append(L"\\");
dstFullPath.Append(fileName);
CString srcFileName = finder.GetFilePath();
CopyFile(srcFileName,dstFullPath.GetBuffer(MAX_PATH),FALSE);
}//end if
}//end while
finder.Close();
}//end func
}//end namespace