C++实现文件夹复制

语言:C++

环境:Windows10 x64 visual sudio 2013

               Linux Ubuntu16.04 gcc

说明:封装了一个类用于复制文件夹到另一指定目录,

       不删除源文件,

       不改变源文件/文件夹名。

注意:只能复制指定文件夹下的文件,

       无法处理子目录(以后再改),

       windows下要用绝对路径。

成员描述:

1、

void copy(const std::string& srcDirPath, const std::string& desDirPath);

类型:公有。

功能:入口函数,给定源文件夹路径()、和目的文件夹路径,会将源文件夹整个存入目标路径下(而不是只保存内容)。

2、
bool make_dir ( const std::string& pathName);

类型:私有。

功能:用于执行创建文件夹操作,需要提供包含路径的完整文件夹名称

3、
bool get_src_files_name(std::vector<std::string>& fileNameList);

类型:私有。

功能:遍历源文件夹下所有文件名,并存入list中。

4、

void do_copy(const std::vector<std::string>& fileNameList);

类型:私有。

功能:对文件夹下的文件进行拷贝操作,使用到了OpenMP做并行支持,简单使用方法见我另外几篇博文。

      http://blog.csdn.net/u012750702/article/details/51476390

      http://blog.csdn.net/u012750702/article/details/51769576


代码:

copy_dir.h 文件

/**
* author : Ladd7
*/

#ifndef COPYDIR_H
#define COPYDIR_H

#include <string>
#include <vector>

class CopyDir
{
public:
    CopyDir();

    void copy(const std::string& srcDirPath, const std::string& desDirPath);

public:

private:
    bool make_dir (const std::string& pathName);
//    bool mkdir (char const* pathname/*, mode_t mode*/);
    bool get_src_files_name(std::vector<std::string>& fileNameList);
    void do_copy(const std::vector<std::string>& fileNameList);

private:
    std::string srcDirPath, desDirPath;


};

#endif // COPYDIR_H

copy_dir.cpp 文件

/**
* author : Ladd7
*/

#include "copy_dir.h"

#include <iostream>
#include <fstream>
#include <cstring>

#if defined(_WIN32)
#   include <direct.h>
#   include <io.h>
#   include <shlobj.h>
#   include <sys/stat.h>
#   include <sys/types.h>
#else // Linux
#   include <dirent.h>
#   include <unistd.h>
#   include <sys/stat.h>
#   include <sys/types.h>
#   include <pwd.h>
#endif

CopyDir::CopyDir()
{

}

void
CopyDir::copy(const std::string& srcDirPath, const std::string& desDirPath)
{
    this->srcDirPath = srcDirPath;
    std::string srcDir;
#ifdef _WIN32
    int n = 0;
    while (srcDirPath.find('\\', n) != std::string::npos)
    {
        n = srcDirPath.find('\\', n) + 1;
    }
    if(n == 0)
    {
        std::cout << "src path error" << std::endl;
        return;
    }
    srcDir = srcDirPath.substr(n-1, srcDirPath.size());

#else  // Linux
    int n = 0;
    while (srcDirPath.find('/', n) != std::string::npos)
    {
        n = srcDirPath.find('/', n) + 1;
    }
    if(n == 0)
    {
        std::cout << "src path error" << std::endl;
        return;
    }
    srcDir = srcDirPath.substr(n-1, srcDirPath.size());

#endif
    this->desDirPath = desDirPath + srcDir;

    if(!make_dir(this->desDirPath))
    {
        return;
    }

    std::vector<std::string> fileNameList;
    if(!get_src_files_name(fileNameList))
    {
        return;
    }

    if(fileNameList.empty())
    {
        std::cout << "src dir is empty" << std::endl;
        return;
    }

    do_copy(fileNameList);
}

bool
CopyDir::make_dir (const std::string& pathName)
{
#ifdef _WIN32
    if(::_mkdir(pathName.c_str()) < 0)
    {
        std::cout << "create path error" << std::endl;
        return false;
    }
#else  // Linux
    if(::mkdir(pathName.c_str(), S_IRWXU | S_IRGRP | S_IXGRP) < 0)
    {
        std::cout << "create path error" << std::endl;
        return false;
    }
#endif

    return true;
}

bool
CopyDir::get_src_files_name(std::vector<std::string>& fileNameList)
{
#ifdef _WIN32
    _finddata_t file;
    long lf;
	std::string src = this->srcDirPath + "\\*.*";
	if ((lf = _findfirst(src.c_str(), &file)) == -1) 
	{
		std::cout << this->srcDirPath << " not found" << std::endl;
		return false;
	}
	else{
		while (_findnext(lf, &file) == 0)
		{
			if (strcmp(file.name, ".") == 0 || strcmp(file.name, "..") == 0)
				continue;
			fileNameList.push_back(file.name);
		}
	}


    _findclose(lf);
#else  // Linux
    DIR *dir;
    struct dirent *ptr;

    if ((dir=opendir(this->srcDirPath.c_str())) == NULL)
    {
		std::cout << this->srcDirPath << " not found" << std::endl;
        return false;
    }

    while ((ptr=readdir(dir)) != NULL)
    {
        if((ptr->d_name == ".") || (ptr->d_name == ".."))  //current / parent
            continue;
        else if(ptr->d_type == 8)  //file
            fileNameList.push_back(ptr->d_name);
        else if(ptr->d_type == 10)  //link file
            continue;
        else if(ptr->d_type == 4)  //dir
            fileNameList.push_back(ptr->d_name);
    }
    closedir(dir);

#endif

    return true;

}

void
CopyDir::do_copy(const std::vector<std::string> &fileNameList)
{
#pragma omp parallel for
    for (int i = 0; i < fileNameList.size(); i++)
    {
        std::string nowSrcFilePath, nowDesFilePath ;
#ifdef _WIN32
		nowSrcFilePath = this->srcDirPath + "\\" + fileNameList.at(i);
		nowDesFilePath = this->desDirPath + "\\" + fileNameList.at(i);

#else
        nowSrcFilePath = this->srcDirPath + "/" + fileNameList.at(i);
        nowDesFilePath = this->desDirPath + "/" + fileNameList.at(i);

#endif
        std::ifstream in;
        in.open(nowSrcFilePath);
        if(!in)
        {
            std::cout << "open src file : " << nowSrcFilePath << " failed" << std::endl;
            continue;
        }

        std::ofstream out;
        out.open(nowDesFilePath);
        if(!out)
        {
            std::cout << "create new file : " << nowDesFilePath << " failed" << std::endl;
            in.close();
            continue;
        }

        out << in.rdbuf();

        out.close();
        in.close();
    }
}


测试:

main.cpp文件

#include <iostream>
#include "copy_dir.h"
using namespace std;

int main(int argc, char *argv[])
{
#ifdef _WIN32
	std::string src = "F:\\data\\test";
	std::string des = "F:\\data\\test2";
	CopyDir cd;
	cd.copy(src, des);
#else
    std::string src = "/media/myUbuntu/F/data/test";
    std::string des = "/media/myUbuntu/F/data/test2";
    CopyDir cd;
    cd.copy(src, des);
#endif
    return 0;
}





  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: c语言遍历文件夹的方法如下: 1. 使用opendir函数打开文件夹, 并使用readdir函数读取文件夹中的文件名。 2. 使用循环遍历文件夹中的所有文件。 3. 对于每一个文件, 使用stat函数获取文件的信息, 包括文件类型(是否是文件夹)。 4. 如果是文件夹, 递归调用此函数, 进入新的文件夹继续遍历。 5. 当文件夹遍历完毕后, 使用closedir函数关闭文件夹。 下面是一个示例代码: ``` #include <stdio.h> #include <dirent.h> #include <sys/stat.h> void listdir(const char *name) { DIR *dir; struct dirent *entry; if (!(dir = opendir(name))) return; while ((entry = readdir(dir)) != NULL) { struct stat st; char path[1024]; snprintf(path, sizeof(path), "%s/%s", name, entry->d_name); if (lstat(path, &st) == -1) continue; if (S_ISDIR(st.st_mode)) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; printf("%*s[%s]\n", indent, "", entry->d_name); listdir(path); } else printf("%*s- %s\n", indent, "", entry->d_name); } closedir(dir); } int main() { listdir("."); return 0; } ``` 希望这个示例代码能够帮助你理解文件夹遍历的方法。 ### 回答2: 遍历文件夹指的是以某种方式遍历文件夹中的所有文件和子文件夹。在计算机编程中,常用的遍历文件夹的方法包括递归和迭代。 递归遍历文件夹是一种深度优先的方式。这种方法会从根文件夹开始,首先获取当前文件夹中的所有文件和子文件夹。然后,对于每个子文件夹,再递归调用遍历文件夹方法,重复上述步骤,直到遍历到最底层的文件夹。这种方式可以确保遍历到文件夹中的每个文件和子文件夹,但可能会消耗较多的内存。 迭代遍历文件夹是一种广度优先的方式。这种方法会使用一个队列来存储待遍历的文件夹。开始时,将根文件夹入队。然后,从队列中取出一个文件夹,获取其中的所有文件和子文件夹,并将它们入队。重复上述步骤,直到队列为空。这种方式可以逐层遍历文件夹,较递归方式占用较少的内存。 在实际编程中,可以根据具体需求选择适合的遍历文件夹的方法。递归方式相对简单,但可能导致栈溢出或死循环等问题。迭代方式相对复杂,但可以灵活控制遍历的深度和顺序。无论选择哪种方式,遍历文件夹都是访问文件系统中重要内容的基本操作之一。 ### 回答3: 遍历文件夹是指对指定文件夹进行逐个查找和检索其中的文件和子文件夹的过程。 在计算机编程中,实现文件夹遍历通常需要使用递归算法。具体步骤如下: 1. 首先,我们需要指定一个顶层文件夹作为起始点。可以是任意一个已存在的文件夹。 2. 然后,我们通过读取起始文件夹的内容(包括文件和子文件夹),获取这些内容的相关信息,例如文件名、文件类型、文件大小等。 3. 对于每一个子文件夹,我们将重复步骤2,进一步查找其中的文件和子文件夹。这就是递归的过程,直到遍历到最底层的文件夹。 4. 遍历文件夹的过程中,可以根据需要进行文件的筛选,例如只处理某些特定类型的文件。 5. 最后,我们可以对遍历到的每一个文件进行自定义的操作,例如打印文件路径复制文件、修改文件等。 通过遍历文件夹,我们可以方便地获取指定文件夹下的所有文件,对其进行批量处理,例如备份、删除、搜索等。这在文件管理、数据处理和程序开发中都是常见的应用场景。 需要注意的是,对于大型文件夹或者文件夹层级很深的情况下,可能会遇到性能问题,因此在实际开发时需要进行优化,例如通过并行处理来提高遍历速度,避免资源浪费和耗时过长。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值