2014-03-05 65 views
0

我是C++的新用戶,我剛剛閱讀了<C++ Primer> 4ed。現在我想實現一個小程序來幫助我管理我的電腦中的一些mp3文件。在C++中查找和移動文件

我有一個.txt文件,其中包含我想移動(不復制)到新文件夾(在同一列中)的文件的所有名稱(實際名稱的一部分)。例如,.txt中的「word」和「file」,我想將文件名爲「word」或「file」的所有.mp3文件移動到新文件夾中。希望我的描述清晰,Opps ..

我知道如何將.txt中的字符串讀入set<string>並遍歷它,但我不知道如何在文件夾中搜索和移動文件。我只想知道我還應該學什麼,以便我可以實現這個功能。我讀C++ Primer仍然我不能做很多事情,這真的很傷心...

+0

C++並不適用於此任務。主要是因爲沒有標準的方式,所以你需要一個圖書館或者自己寫一切。這當然是可能的,但你可能更適合使用腳本解決方案。 – stefan

+1

那麼標準的C++庫並沒有在這些任務中開發。沒有什麼可以支持os文件系統操作。不過,如果我決心讓[boost :: filesystem](http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html#rename)堅持使用C++。但對於這樣的事情,我更喜歡python。 – luk32

+0

我也會使用Boost.Filesystem,至少在出現寬C++ 14支持之前。 –

回答

1

這隻能使用std的唯一方法是使用std::ifstream完全讀取文件,然後將其寫入新的地址爲std::ofstream。但是這不會從磁盤中刪除舊文件。所以基本上你會創建一個文件的副本。它也比真實的移動慢得多。

最佳解決方案是使用特定於操作系統的API,例如win32,例如提供MoveFile()函數。 Poco提供了這種API的平臺獨立抽象。請參閱:http://www.appinf.com/docs/poco/Poco.File.html

-1

在Windows下運行system電話與批處理命令:

system("move *text*.mp3 new_folder/"); 
system("move *word*.mp3 new_folder/"); 

在Unix下,用相同的shell語法。

2

要在C++中移動文件,您不必使用外部庫,如Boost.Filesystem,但可以使用標準功能。

有新filesystem API,其中有一個rename功能:

#include <iostream> 
#include <filesystem> 

int main() { 
    try { 
    std::filesystem::rename("from.txt", "to.txt"); 
    } catch (std::filesystem::filesystem_error& e) { 
    std::cout << e.what() << '\n'; 
    } 
    return 0; 
} 

的缺點是編譯它,你需要最新的C++編譯器17。 (我在gcc 8.0.1上測試過,我也需要鏈接到-lstdc++fs)。

但是,如果任何C++編譯器今天的工作時,是舊的C API,它也提供了rename (cstdio)

#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <cerrno> 

int main() { 
    if(std::rename("from.txt", "to.txt") < 0) { 
    std::cout << strerror(errno) << '\n'; 
    } 
    return 0; 
} 

但需要注意的是,在這兩種情況下,重命名會如果源文件和目標文件都是失敗不在同一個文件系統上。然後你會看到這樣的錯誤:

filesystem error: cannot rename: Invalid cross-device link [from.txt] [/tmp/to.txt] 

在這種情況下,你只能做一個副本,然後刪除原始文件:

#include <fstream> 
#include <iostream> 
#include <ios> 
#include <cstdio> 

int main() { 
    std::ifstream in("from.txt", std::ios::in | std::ios::binary); 
    std::ofstream out("to.txt", std::ios::out | std::ios::binary); 
    out << in.rdbuf(); 
    std::remove("from.txt"); 
} 

或者用新的API:

#include <iostream> 
#include <filesystem> 

int main() 
{ 
    try { 
    std::filesystem::copy("from.txt", "to.txt"); 
    std::filesystem::remove("from.txt"); 
    } catch (std::filesystem::filesystem_error& e) { 
    std::cout << e.what() << '\n'; 
    } 
    return 0; 
}