2017-09-04 154 views
2

對數字目錄的子文件夾和文件名進行排序我使用的是與增強tutorials中相同的示例。但由於我的文件名被編號(1,20,23,..)。代碼無法比較字符串(例如20 < 7)。有沒有辦法以數字方式比較directory_iteration。這裏是使用boost :: filesystem

else if (is_directory(p))  // is p a directory? 
     { 
     cout << p << " is a directory containing:\n"; 

     typedef vector<path> vec;    // store paths, 
     vec v;        // so we can sort them later 

     copy(directory_iterator(p), directory_iterator(), back_inserter(v)); 

     sort(v.begin(), v.end());    // **I want to sort this numerically** 

     for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) 
     { 
      cout << " " << *it << '\n'; 
     } 
     } 

目錄和子文件夾的佈局如下所示的代碼片段:

root/ 
    1/ 
    1.bmp 
    2.bmp 
    3.bmp 
    4.bmp 
    ... 
    2/ 
    1.bmp 
    2.bmp 
    3.bmp 
    4.bmp 
    .... 
    3/ 
    1.bmp 
    2.bmp 
    3.bmp 
    4.bmp 
    .... 
+1

下一次使用的數位的固定數量(給在你的文件名中使用0-padding來調用所有使用的值),問題就會消失。例如,當我們預計至多有100個文件(0-99)將文件命名爲「01.txt」,「20.txt」,「23.txt」等。現在你必須解析文件名的數值並用它來排序。 –

+0

@DanMašek這些文件是由另一個軟件自動生成的,我不知道我可以編輯它,因爲它是一個商業軟件。我必須與我所擁有的一起工作。我有超過50個子文件夾,每個文件夾的編號從1:127開始,它會自動重命名它們。 Thnx – Bob

+1

使用自定義比較器從路徑中獲取這些數字並進行比較。 –

回答

2

既然你不能改變文件名格式爲可排序的是,你將需要自己做一些處理 - 從每個文件名解析數字,然後用它進行排序。想起兩種方法,在內存和CPU使用率之間進行折衷。

方法1:

文件名和數值的存儲對,填充載體時解析。

方法2:

只存儲路徑並在比較過程中執行轉換。


代碼:目錄

#include <boost/filesystem/path.hpp> 
#include <boost/filesystem/operations.hpp> 
#include <iostream> 

namespace fs = boost::filesystem; 

int parse_filename(fs::path const& p) 
{ 
    return std::stoi(p.filename().string()); 
} 

void sort_numeric_1(fs::path const& p) 
{ 
    typedef std::pair<fs::path, int> file_entry; 
    typedef std::vector<file_entry> vec; 
    vec v; 

    for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it) { 
     v.emplace_back(*it, parse_filename(*it)); 
    } 

    std::sort(v.begin(), v.end() 
     , [](file_entry const& a, file_entry const& b) { 
     return a.second < b.second; 
    }); 

    for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { 
     std::cout << " " << it->first << '\n'; 
    } 
} 

void sort_numeric_2(fs::path const& p) 
{ 
    typedef std::vector<fs::path> vec; 
    vec v; 

    std::copy(fs::directory_iterator(p), fs::directory_iterator(), back_inserter(v)); 

    std::sort(v.begin(), v.end() 
     , [](fs::path const& a, fs::path const& b) { 
     return std::stoi(a.filename().string()) < std::stoi(b.filename().string()); 
    }); 

    for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { 
     std::cout << " " << *it << '\n'; 
    } 
} 

int main() 
{ 
    sort_numeric_1("test"); 
    std::cout <<"\n"; 
    sort_numeric_2("test"); 
} 

內容:

> ls test 
1.txt 10.txt 127.txt 20.txt 23.txt 

輸出:

"test\1.txt" 
"test\10.txt" 
"test\20.txt" 
"test\23.txt" 
"test\127.txt" 

"test\1.txt" 
"test\10.txt" 
"test\20.txt" 
"test\23.txt" 
"test\127.txt" 

它更新爲h andle還有你的整個目錄結構,你可以有這樣的事情:

  • 先找到所有的目錄,並將其數字排序
  • 然後在每個找到的目錄
  • 合併所有的文件進行排序文件
  • 的排序的列表

實施例:

#include <boost/filesystem/path.hpp> 
#include <boost/filesystem/operations.hpp> 
#include <iostream> 

namespace fs = boost::filesystem; 

typedef std::vector<fs::path> path_vec; 

void sort_numeric(path_vec& v) 
{ 
    std::sort(v.begin(), v.end() 
     , [](fs::path const& a, fs::path const& b) { 
     return std::stoi(a.filename().string()) < std::stoi(b.filename().string()); 
    }); 
} 

path_vec sort_root_dir(fs::path const& p) 
{ 
    path_vec dirs; 

    for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it) { 
     if (is_directory(*it)) { 
      dirs.emplace_back(*it); 
     } 
    } 

    sort_numeric(dirs); 

    path_vec files; 
    for (path_vec::const_iterator it(dirs.begin()), it_end(dirs.end()); it != it_end; ++it) { 
     path_vec dir_files; 
     std::copy(fs::directory_iterator(*it), fs::directory_iterator(), back_inserter(dir_files)); 
     sort_numeric(dir_files); 
     files.insert(files.end(), dir_files.begin(), dir_files.end()); 
    } 

    return files; 
} 

int main() 
{ 
    path_vec files = sort_root_dir("test"); 

    for (auto const& f : files) { 
     std::cout << f << "\n"; 
    } 
} 
+0

這工作完美,如果我只有一個子文件夾,爲多個子文件夾它失敗,並給我(終止後拋出'std :: invalid_argument'實例什麼():stoi)調用。 – Bob

+0

這只是一個簡單的例子,說明如何使用文件對單個目錄進行排序。您將不得不添加一些額外的檢查來處理嵌套的目錄。也許如果你能向我們展示目錄樹佈局的一些例子(所以我們知道會發生什麼),你可以有更完整的解決方案。 –

+1

我剛剛更新了問題 – Bob

相關問題