一点一滴成长

导航

boost--文件、目录操作

  filesystem库是文件系统操作库,可以使用其中的basic_path类用来操作目录、文件,使用需要包含编译好的system库和filesystem库,我们一般不直接使用basic_path,而是使用typedef : path和wpath。 使用它需要包含"boost/filesystem.hpp"。

    boost::filesystem::path p1("D:\\dir"); //windows下既可使用斜杠也可使用反斜杠(资源管理器地址栏中使用的就是反斜杠),又因为在c++中反斜杠是转义字符的标志,所以使用反斜杠的话还得再加一个反斜杠
    boost::filesystem::path p2("D:/dir/data.dat"); //windows下推荐使用正斜杠
    boost::filesystem::path p3("/user/dir"); //linux下使用正斜杠
    boost::filesystem::path p4 = "./dir"; //path的构造函数没有声明为explicit,字符串可以隐式转换为path对象

    p1 /= "child"; //path重载了 /=,其功能与成员append()相同。
    cout << p1 << endl; //支持流输出操作,输出为"D:\dir\child"
    
    if (p1 == p2); //支持比较操作
    auto iter = p1.begin(); //支持迭代器来迭代其中的字符串

    std::string strDir = p1.string(); //获取字符串(构造函数中传入的字符串为相对路径的话这里也是相对路径)
    bool bRes = boost::filesystem::portable_posix_name(strDir); //判断是否符合posix文件命名规范
    boost::filesystem::windows_name(strDir); //判断是否符合windows文件命名规范
    boost::filesystem::portable_name(strDir); //相当于portable_posix_name() && windows_name
    boost::filesystem::native(strDir); //在windows下相当于windows_name,其它操作系统下只是简单的判断文件名不是空格且不含斜杠

    boost::filesystem::path parentPath = p3.parent_path(); //获得父路径
    boost::filesystem::path parentPath = p3.system_complete(); //获得全路径(绝对路径)
    std::string name = p2.filename().string(); //文件名: data.dat
    std::string s = p2.stem().string(); //不含扩展名的文件名: data
    std::string extName = p2.extension().string(); //扩展名: dat

    p1.is_complete(); //是否是一个完整的绝对路径
    p1.relative_path(); //获得path的相对路径

    boost::filesystem::path p("C:/xxx/yyy");
    p1.root_path(); //根路径: "C:/"
    p1.root_name(); //根名字:"C:"
    p1.root_directory(); //根目录: "/"

    p1.remove_filename(); //删除当前路径中最后的文件名
    p1.replace_extension("hxx"); //改变文件扩展名

    // filesystem使用异常来处理文件操作时发生的错误,所以使用的时候应该加上异常处理
    try
    {
        boost::filesystem::file_size(p1); //获得文件大小,文件不存在则会抛出异常
    }
    catch (boost::filesystem::filesystem_error& e)
    {
        cout << e.path1() << endl;
        cout << e.what() << endl;
    }

    boost::filesystem::exists(p1); //是否存在
    boost::filesystem::is_directory(p1); //是否是目录
    boost::filesystem::is_regular_file(p1); //是否是普通文件
    boost::filesystem::is_empty(p1); //目录是否为空或文件大小是否为0
    boost::filesystem::is_symlink(p1); //是否为链接文件
    boost::filesystem::is_other(p1); //当文件存在且不是普通文件、目录或链接文件时返回true,其它文件类型可以通过文件状态类file_status获得

    boost::filesystem::current_path(); //获得当前路径
    boost::filesystem::initial_path(); //获得进入main函数时的当前路径
    boost::filesystem::last_write_time(p1); //获得文件最后修改时间
    boost::filesystem::space(p1); //获得路径下磁盘空间分配情况

    boost::filesystem::remove(p1); //删除文件或空目录
    boost::filesystem::remove_all(p1); //删除目录
    boost::filesystem::create_directory(p1); //创建一级目录
    boost::filesystem::create_directories(p1); //创建多级目录
    boost::filesystem::copy_file(p1, p2); //拷贝
    boost::filesystem::rename(p1, p2); //改名

    void recursive_dir(const boost::filesystem::path& dir)
    {
        //使用directory_iterator递归遍历目录
        boost::filesystem::directory_iterator end; //空的directory_iterator构造函数生成一个指向end的迭代器
        boost::filesystem::directory_iterator pos(p1); //传入一个path对象后可以使用++开始迭代操作
        for (; pos != end; pos++)
        {
            if (boost::filesystem::is_directory(*pos))
                recursive_dir(*pos); //directory_iterator迭代器返回的类型其实不是path,但它定义了一个到path的类型转换函数,因此这里是隐式转换
            else
                cout << *pos << endl;  //输出文件名
        }
    }
    
    //directory_iterator不支持深度遍历,可以使用效率更高的recursive_directory_iterator或wrecursive_directory_iterator
    typedef boost::filesystem::recursive_directory_iterator rd_iterator;
    rd_iterator end;
    rd_iterator pos(p1);
    for (; pos != end; pos++)
    {
        //if (boost::filesystem::is_directory(*pos))
            //pos.no_push(); //退出当前目录层次的遍历,相当于使用directory_iterator

        cout << pos.level() << endl; //获得当前目录深度
        cout << *pos << endl; //输出文件名
    }

 获得目录大小:

#include <numeric>
#include "boost/filesystem.hpp"
namespace fs = boost::filesystem;

boost::uintmax_t getDirSize(const fs::path& p)
{
    return std::accumulate(
        boost::make_transform_iterator<boost::uintmax_t(*)(const fs::path&), fs::recursive_directory_iterator>(fs::recursive_directory_iterator(p), [](const fs::path& p)->boost::uintmax_t {return fs::is_directory(p) ? 0 : fs::file_size(p); }),
        boost::make_transform_iterator<boost::uintmax_t(*)(const fs::path&), fs::recursive_directory_iterator>(fs::recursive_directory_iterator(), [](const fs::path& p)->boost::uintmax_t {return fs::is_directory(p) ? 0 : fs::file_size(p); }),
        static_cast <boost::uintmax_t>(0));
}

std::accumulate()可以进行累加操作,比如 int sum = accumulate(vec.begin(), vec.end(), 42) ,前两个参数指定要累加的元素范围,第三个参数则是累加的初值,再比如 string sum = accumulate(v.begin(), v.end(), string("connect_value: "))。对于自定义数据类型,需要提供一个回调函数来实现自定义数据的处理,作为accumulate()的第四个参数:

struct Grade  
{  
    string name;  
    int grade;  
};  
  
int main()  
{  
    Grade subject[3] = {  
        { "English", 80 },  
        { "Biology", 70 },  
        { "History", 90 }  
    };  
  
    int sum = accumulate(subject, subject + 3, 0, [](int a, Grade b){return a + b.grade; });  
    cout << sum << endl;  
  
    return 0;  
}

 

posted on 2019-04-23 15:50  整鬼专家  阅读(6814)  评论(0编辑  收藏  举报