簡體   English   中英

C ++將所有文件從一個目錄移動到另一個目錄

[英]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)closedirstat(2) (您可以直接使用)。

對於最近的 C++17 實現,您可能會使用<filesystem>

如果其他進程正在寫入子目錄,您可能會遇到麻煩(可能是mv )。

也許在另一個進程中運行/bin/mv (該文件路徑由 POSIX 標准化)可能更簡單。

如果/testdir/testdest位於不同的文件系統(和掛載點)中,則可能會出現問題,因為rename(2)僅適用於一個文件系統。 mv知道如何處理(在這種情況下,它會在刪除源之前復制文件)。 此外, /testdir的一些子目錄可能是掛載點等。

如果/testdir//testdest/都在同一個文件系統中,並且/testdir下沒有掛載點,則可以循環使用opendirreaddirclosedir ,跳過. ..條目,為每個目錄條目構造相應的完整源路徑和目標路徑,並在這些路徑上使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM