2017-09-04 150 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

相关问题