[英]C++ move all files from one directory to another
我在將數據從一個目錄移動到另一個目錄時遇到問題。 我想做如下(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/
不再可用,這不是預期的結果。
// 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...
您可以使用nftw(3)收集所有路徑,然后在mkdir(2)和rename(2)上循環。 nftw
使用opendir(3) , readdir(3) , closedir
, stat(2) (您可以直接使用)。
對於最近的 C++17 實現,您可能會使用<filesystem>
如果其他進程正在寫入子目錄,您可能會遇到麻煩(可能是mv
)。
也許在另一個進程中運行/bin/mv
(該文件路徑由 POSIX 標准化)可能更簡單。
如果/testdir
和/testdest
位於不同的文件系統(和掛載點)中,則可能會出現問題,因為rename(2)僅適用於一個文件系統。 mv
知道如何處理(在這種情況下,它會在刪除源之前復制文件)。 此外, /testdir
的一些子目錄可能是掛載點等。
如果/testdir/
和/testdest/
都在同一個文件系統中,並且/testdir
下沒有掛載點,則可以循環使用opendir
、 readdir
、 closedir
,跳過.
和..
條目,為每個目錄條目構造相應的完整源路徑和目標路徑,並在這些路徑上使用rename
。
當然, mv
是自由軟件,在GNU coreutils
中,你可以研究它的源代碼(它不像你想象的那么簡單,因為它處理了極端情況)。 您還可以使用strace(1)來了解某些mv
命令或進程涉及哪些系統調用(在syscalls(2)中列出)。
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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.