C ++将所有文件从一个目录移动到另一个目录

时间:2018-05-14 13:01:31

标签: c++ linux file

将数据从一个目录移动到另一个目录时遇到问题。 我想做如下(bash),但在C ++中:

mv /testdir/* /testdest/

因此它应该基本上将/testdir中的所有文件移动到/testdest。 我已经在C ++中尝试了rename,但它实际上并没有移动数据,它只是重命名目录。

我目前的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <unistd.h>
#include <dirent.h>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sys/stat.h>
#include <syslog.h>
#include <fstream>

using namespace std;

int main( int argc, char *argv[] )
{
  rename (argv[1], argv[2])
}

我正在执行以下操作:

./static-mv /testdir/ /testdest/

这样做的效果是将/testdir/重命名为/testdest/(及其内容)。 在此之后,/testdir/不再可用,这不是预期的结果。

3 个答案:

答案 0 :(得分:1)

您可以使用nftw(3)收集所有路径,然后循环mkdir(2)&amp; rename(2)container使用opendir(3)readdir(3)nftwstat(2)(您可以直接使用)。

使用最近的C ++ 17实现,您可以使用<filesystem>

如果某些其他进程正在写入子目录,则可能会出现问题(可能是closedir)。

在另一个进程中运行mv(该文件路径由POSIX标准化)可能更简单。

如果/bin/mv/testdir位于不同的文件系统(和挂载点)中,则可能会出现问题,因为rename(2)仅适用于一个文件系统。 /testdest知道如何处理(在这种情况下,它在删除源之前复制文件)。此外,mv的某些子目录可能是挂载点等。

如果/testdir/testdir/位于同一个文件系统中且/testdest/下没有挂载点,则可以循环使用/testdir,{{1} },opendir,跳过readdirclosedir条目,为每个目录条目构建相应的完整源和目标路径,并在这些路径上使用.

当然,..GNU coreutils中的免费软件,你可能会研究它的源代码(它可能不那么简单,因为它可以处理极端情况)。您还可以使用strace(1)了解某些rename命令或进程所涉及的system callssyscalls(2)中列出的内容)。

答案 1 :(得分:0)

void move(char const *sorc, char const *dst, bool createRoot = true) {
    namespace fs = std::experimental::filesystem;

    if (createRoot)
        fs::create_directory(dst);

    for(fs::path p: fs::directory_iterator(sorc)){
        fs::path destFile = dst/p.filename();

        if (fs::is_directory(p)) {
            fs::create_directory(destFile);
            move(p.string().c_str(), destFile.string().c_str(), false);
        } else {
            //std::cout << "updated " << p.string().c_str() << std::endl;
            fs::rename(p, destFile);
        }
    }
}

答案 2 :(得分:-1)

// static-mv.cpp
#include<experimental/filesystem>
#include<cassert>
#include<iostream>

int main(int argc, char* argv[]){
    assert(argc >= 3);
    namespace fs = std::experimental::filesystem;
    for(fs::path p : fs::directory_iterator(argv[1])){
        std::cout << p << " -> " << argv[2]/p.filename() << std::endl;
        fs::rename(p, argv[2]/p.filename());
    }
}

$ c++ -std=c++11 static-mv.cpp -o static-mv -lstdc++fs

$ mkdir dir1; cd dir1; touch file.a; touch file.b; cd ..; ls dir1/

file.a  file.b

$ mkdir dir2;

$ ./static-mv dir1 dir2

"dir1/file.a" -> "dir2/file.a"
"dir1/file.b" -> "dir2/file.b"

$ ls dir2/

file.a  file.b

$ success!

bash: success!: command not found...