博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
文件夹操作:复制和删除整个文件夹
阅读量:4618 次
发布时间:2019-06-09

本文共 9199 字,大约阅读时间需要 30 分钟。

转载请注明原文链接。

原文链接:

文件和文件夹的创建、复制、删除、重命名等操作是经常要用到的,作者根据自己的经验,并查询了MSDN,特意总结了常用文件和文件夹的相关操作,重点讨论了复制整个文件夹和删除整个文件夹

1、文件操作基本函数

WinBase.h中声明了Windows平台下的基本的API函数,包括文件和目录的基本操作。

下面列出部分常用的文件操作相关函数。

函数

说明

DeleteFile

删除单个文件,不能删除目录和只读文件

CopyFile

复制单个文件

MoveFile

移动移动文件或目录

CreateDirectory

创建目录

RemoveDirectory

删除空目录

 

更多的函数可查询Winbase.h文件或者MSDN中的File Management FunctionsDirectory Management Functions 。

 

2、复制目录和删除目录

WinBase.h中的文件操作函数中并没有直接实现整个文件夹的复制和删除操作的函数,需要自己实现。

(1)判断指定路径是否有效目录

1 /*判断一个路径是否是已存在的目录*/  2 BOOL IsDirectory(LPCTSTR pstrPath)  3 {
4 if (NULL == pstrPath) 5 {
6 return FALSE; 7 } 8 9 /*去除路径末尾的反斜杠*/ 10 CString strPath = pstrPath; 11 if (strPath.Right(1) == _T('\\')) 12 {
13 strPath.Delete(strPath.GetLength()-1); 14 } 15 16 CFileFind finder; 17 BOOL bRet = finder.FindFile(strPath); 18 if (!bRet) 19 {
20 return FALSE; 21 } 22 23 /*判断该路径是否是目录*/ 24 finder.FindNextFile(); 25 bRet = finder.IsDirectory(); 26 finder.Close(); 27 return bRet; 28 }

(2)复制目录

复制目录函数的大致思路为:查找目录中所有文件,如果是文件直接复制,如果是目录,则递归调用目录复制函数。

1 /*复制目录中的所有内容*/  2 BOOL CopyFolder(LPCTSTR pstrSrcFolder, LPCTSTR pstrDstFolder)  3 {
4 if ((NULL == pstrSrcFolder) || (NULL == pstrSrcFolder)) 5 {
6 return FALSE; 7 } 8 9 /*检查源目录是否是合法目录*/ 10 if (!IsDirectory(pstrSrcFolder)) 11 {
12 return FALSE; 13 } 14 15 /*把文件名称转换为CString类型,并确认目录的路径末尾为反斜杠*/ 16 CString strSrcFolder(pstrSrcFolder); 17 if (strSrcFolder.Right(1) != _T('\\')) 18 {
19 strSrcFolder += _T("\\"); 20 } 21 CString strDstFolder(pstrDstFolder); 22 if (strDstFolder.Right(1) != _T("\\")) 23 {
24 strDstFolder += _T("\\"); 25 } 26 27 /*如果是目录自身复制,直接返回复制成功*/ 28 if (0 == _tcscmp(strSrcFolder, strDstFolder)) 29 {
30 return TRUE; 31 } 32 33 /*如果目的目录不存在,则创建目录*/ 34 if (!IsDirectory(strDstFolder)) 35 {
36 if (!CreateDirectory(strDstFolder, NULL)) 37 {
38 /*创建目的目录失败*/ 39 return FALSE; 40 } 41 } 42 43 /*创建源目录中查找文件的通配符*/ 44 CString strWildcard(strSrcFolder); 45 strWildcard += _T("*.*"); 46 47 /*打开文件查找,查看源目录中是否存在匹配的文件*/ 48 /*调用FindFile后,必须调用FindNextFile才能获得查找文件的信息*/ 49 CFileFind finder; 50 BOOL bWorking = finder.FindFile(strWildcard); 51 52 while (bWorking) 53 {
54 /*查找下一个文件*/ 55 bWorking = finder.FindNextFile(); 56 57 /*跳过当前目录“.”和上一级目录“..”*/ 58 if (finder.IsDots()) 59 {
60 continue; 61 } 62 63 /*得到当前要复制的源文件的路径*/ 64 CString strSrcFile = finder.GetFilePath(); 65 66 /*得到要复制的目标文件的路径*/ 67 CString strDstFile(strDstFolder); 68 strDstFile += finder.GetFileName(); 69 70 /*判断当前文件是否是目录,*/ 71 /*如果是目录,递归调用复制目录,*/ 72 /*否则,直接复制文件*/ 73 if (finder.IsDirectory()) 74 {
75 if (!CopyFolder(strSrcFile, strDstFile)) 76 {
77 finder.Close(); 78 return FALSE; 79 } 80 } 81 else 82 {
83 if (!CopyFile(strSrcFile, strDstFile, FALSE)) 84 {
85 finder.Close(); 86 return FALSE; 87 } 88 } 89 90 } /*while (bWorking)*/ 91 92 /*关闭文件查找*/ 93 finder.Close(); 94 95 return TRUE; 96 97 }

 

(3)删除目录

删除目录的思路和复制目录的思路类似,也是采用递归的方法。

 

1 /*删除目录及目录中的所有内容*/  2 BOOL DeleteFolder(LPCTSTR pstrFolder)  3 {
4 if ((NULL == pstrFolder)) 5 {
6 return FALSE; 7 } 8 9 /*检查输入目录是否是合法目录*/ 10 if (!IsDirectory(pstrFolder)) 11 {
12 return FALSE; 13 } 14 15 /*创建源目录中查找文件的通配符*/ 16 CString strWildcard(pstrFolder); 17 if (strWildcard.Right(1) != _T('\\')) 18 {
19 strWildcard += _T("\\"); 20 } 21 strWildcard += _T("*.*"); 22 23 /*打开文件查找,查看源目录中是否存在匹配的文件*/ 24 /*调用FindFile后,必须调用FindNextFile才能获得查找文件的信息*/ 25 CFileFind finder; 26 BOOL bWorking = finder.FindFile(strWildcard); 27 28 while (bWorking) 29 {
30 /*查找下一个文件*/ 31 bWorking = finder.FindNextFile(); 32 33 /*跳过当前目录“.”和上一级目录“..”*/ 34 if (finder.IsDots()) 35 {
36 continue; 37 } 38 39 /*得到当前目录的子文件的路径*/ 40 CString strSubFile = finder.GetFilePath(); 41 42 /*判断当前文件是否是目录,*/ 43 /*如果是目录,递归调用删除目录,*/ 44 /*否则,直接删除文件*/ 45 if (finder.IsDirectory()) 46 {
47 if (!DeleteFolder(strSubFile)) 48 {
49 finder.Close(); 50 return FALSE; 51 } 52 } 53 else 54 {
55 if (!DeleteFile(strSubFile)) 56 {
57 finder.Close(); 58 return FALSE; 59 } 60 } 61 62 } /*while (bWorking)*/ 63 64 /*关闭文件查找*/ 65 finder.Close(); 66 67 /*删除空目录*/ 68 return RemoveDirectory(pstrFolder); 69 }

 

 

3shlwapi.h中的文件操作函数

shlwapi.hshlwapi.dll头文件,shlwapi.dllMicrosoft Shell Light-weight Utility Library)中定义了路径相关的操作,也包括了部分文件操作函数。由于shlwapi.dll属于Microsoft Windows Shell,因此这些文件操作特点与通过Shell进行文件操作类似。

下面列出部分常用的文件操作相关函数。

 

PathIsDirectory

判断一个路径是否有效目录

PathIsDirectoryEmpty

判断一个路径是否空目录

PathFileExists

判断一个路径是否有效目录或文件

PathRenameExtension

更改文件的后缀名

SHFileOperation

可实现文件或目录的复制、移动、重命名和删除操作,并可一次操作多个文件或目录

 

其中,SHFileOperation可实现整个目录的内容的复制和删除。SHFileOperation可一次实现多个目录的复制或删除,其输入参数结构体SHFILEOPSTRUCT中的pFrom(源目录)和pTo(目的目录)都可以输入多个目录,目录之间通过'\0'分割,pFrompTo必须以2'\0'结尾。一般情况下,我们都只是对一个目录操作,因此,SHFileOperation调用并不是很方便,下面就对SHFileOperation进行包装,提供更方便调用的目录操作函数。

具体的代码实现如下:

1)复制目录

 

1 /*通过调用ShFileOperation来实现整个目录的复制*/  2 /*只复制单个目录*/  3 /*如果目标目录已存在,将把源目录作为目的目录的子目录*/  4 /*如果要实现完全覆盖,需要先删除目的目录*/  5 BOOL SHCopyFolder(LPCTSTR pstrSrcFolder, LPCTSTR pstrDstFolder)  6 {
7 if ((NULL == pstrSrcFolder) || (NULL == pstrSrcFolder)) 8 {
9 return FALSE; 10 } 11 12 int iSrcPathLen = _tcslen(pstrSrcFolder); 13 int iDstPathLen = _tcslen(pstrDstFolder); 14 if ((iSrcPathLen >= MAX_PATH) || (iDstPathLen >= MAX_PATH)) 15 {
16 return FALSE; 17 } 18 19 /*确保源目录的路径以2个\0结尾*/ 20 TCHAR tczSrcFolder[MAX_PATH+1]; 21 ZeroMemory(tczSrcFolder, (MAX_PATH+1)*sizeof(TCHAR)); 22 _tcscpy(tczSrcFolder, pstrSrcFolder); 23 tczSrcFolder[iSrcPathLen] = _T('\0'); 24 tczSrcFolder[iSrcPathLen+1] = _T('\0'); 25 26 /*确保目的目录的路径以2个\0结尾*/ 27 TCHAR tczDstFolder[MAX_PATH+1]; 28 ZeroMemory(tczDstFolder, (MAX_PATH+1)*sizeof(TCHAR)); 29 _tcscpy(tczDstFolder, pstrDstFolder); 30 tczDstFolder[iDstPathLen] = _T('\0'); 31 tczDstFolder[iDstPathLen+1] = _T('\0'); 32 33 SHFILEOPSTRUCT FileOp; 34 ZeroMemory(&FileOp, sizeof(SHFILEOPSTRUCT)); 35 FileOp.fFlags |= FOF_SILENT; /*不显示进度*/ 36 FileOp.fFlags |= FOF_NOERRORUI ; /*不报告错误信息*/ 37 FileOp.fFlags |= FOF_NOCONFIRMATION;/*不进行确认*/ 38 FileOp.hNameMappings = NULL; 39 FileOp.hwnd = NULL; 40 FileOp.lpszProgressTitle = NULL; 41 FileOp.wFunc = FO_COPY; 42 FileOp.pFrom = tczSrcFolder; /*源目录,必须以2个\0结尾*/ 43 FileOp.pTo = tczDstFolder; /*目的目录,必须以2个\0结尾*/ 44 45 /*复制目录*/ 46 if (0 == SHFileOperation(&FileOp)) 47 {
48 return TRUE; 49 } 50 else 51 {
52 return FALSE; 53 } 54 55 }

 

2)删除目录

 

1 /*通过调用ShFileOperation来实现整个目录的删除*/  2 /*只删除单个目录*/  3 BOOL CFolder::SHDeleteFolder(LPCTSTR pstrFolder, BOOL bAllowUndo)  4 {
5 if ((NULL == pstrFolder)) 6 {
7 return FALSE; 8 } 9 10 int iPathLen = _tcslen(pstrFolder); 11 if (iPathLen >= MAX_PATH) 12 {
13 return FALSE; 14 } 15 16 /*确保目录的路径以2个\0结尾*/ 17 TCHAR tczFolder[MAX_PATH+1]; 18 ZeroMemory(tczFolder, (MAX_PATH+1)*sizeof(TCHAR)); 19 _tcscpy(tczFolder, pstrFolder); 20 tczFolder[iPathLen] = _T('\0'); 21 tczFolder[iPathLen+1] = _T('\0'); 22 23 SHFILEOPSTRUCT FileOp; 24 ZeroMemory(&FileOp, sizeof(SHFILEOPSTRUCT)); 25 FileOp.fFlags |= FOF_SILENT; /*不显示进度*/ 26 FileOp.fFlags |= FOF_NOERRORUI; /*不报告错误信息*/ 27 FileOp.fFlags |= FOF_NOCONFIRMATION;/*直接删除,不进行确认*/ 28 FileOp.hNameMappings = NULL; 29 FileOp.hwnd = NULL; 30 FileOp.lpszProgressTitle = NULL; 31 FileOp.wFunc = FO_DELETE; 32 FileOp.pFrom = tczFolder; /*要删除的目录,必须以2个\0结尾*/ 33 FileOp.pTo = NULL; 34 35 /*根据传递的bAllowUndo参数确定是否删除到回收站*/ 36 if (bAllowUndo) 37 { 38 FileOp.fFlags |= FOF_ALLOWUNDO; /*删除到回收站*/ 39 } 40 else 41 { 42 FileOp.fFlags &= ~FOF_ALLOWUNDO; /*直接删除,不放入回收站*/ 43 } 44 45 /*删除目录*/ 46 if (0 == SHFileOperation(&FileOp)) 47 {
48 return TRUE; 49 } 50 else 51 {
52 return FALSE; 53 } 54 }

 

4、示例工程

作者通过VC6.0和VS2010分别针对以上代码创建了示例工程,在工程中,把以上函数封装到CFolder类中,并把所有函数设置为静态函数。在示例工程中,分别对这些函数进行了调用测试。

工程文件下载:

PUDN:

CSDN:

 

5、参考资料

(1)、File Management Functions

(2)、Directory Management Functions

转载于:https://www.cnblogs.com/xianyunhe/archive/2011/12/06/2278550.html

你可能感兴趣的文章
2016.10.24 继续学习
查看>>
产品功能对标 - 服务授权管理
查看>>
各地IT薪资待遇讨论
查看>>
splay入门
查看>>
带CookieContainer进行post
查看>>
C语言学习笔记--字符串
查看>>
关于七牛进行图片添加文字水印操作小计
查看>>
DataSource数据库的使用
查看>>
Luogu4069 SDOI2016 游戏 树链剖分、李超线段树
查看>>
Java的内部类真的那么难以理解?
查看>>
一文搞懂Java环境,轻松实现Hello World!
查看>>
hash实现锚点平滑滚动定位
查看>>
也谈智能手机游戏开发中的分辨率自适应问题
查看>>
关于 IOS 发布的点点滴滴记录(一)
查看>>
《EMCAScript6入门》读书笔记——14.Promise对象
查看>>
CSS——水平/垂直居中
查看>>
Eclipse连接mysql数据库jdbc下载(图文)
查看>>
Python中Selenium的使用方法
查看>>
三月23日测试Fiddler
查看>>
20171013_数据库新环境后期操作
查看>>