MFC复制目录树

这篇博客记录了如何在MFC应用中实现复制目录树的功能,包括 FireDirHelper 类的头文件和源代码实现。
摘要由CSDN通过智能技术生成

这里记一下,免得要用的时候,东找西找。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kagula086

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值