将数据从一个目录移动到另一个目录时遇到问题。 我想做如下(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/
不再可用,这不是预期的结果。
答案 0 :(得分:1)
您可以使用nftw(3)收集所有路径,然后循环mkdir(2)&amp; rename(2)。 container
使用opendir(3),readdir(3),nftw
,stat(2)(您可以直接使用)。
使用最近的C ++ 17实现,您可以使用<filesystem>
如果某些其他进程正在写入子目录,则可能会出现问题(可能是closedir
)。
在另一个进程中运行mv
(该文件路径由POSIX标准化)可能更简单。
如果/bin/mv
和/testdir
位于不同的文件系统(和挂载点)中,则可能会出现问题,因为rename(2)仅适用于一个文件系统。 /testdest
知道如何处理(在这种情况下,它在删除源之前复制文件)。此外,mv
的某些子目录可能是挂载点等。
如果/testdir
和/testdir/
位于同一个文件系统中且/testdest/
下没有挂载点,则可以循环使用/testdir
,{{1} },opendir
,跳过readdir
和closedir
条目,为每个目录条目构建相应的完整源和目标路径,并在这些路径上使用.
。
当然,..
是GNU coreutils
中的免费软件,你可能会研究它的源代码(它可能不那么简单,因为它可以处理极端情况)。您还可以使用strace(1)了解某些rename
命令或进程所涉及的system calls(syscalls(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...