zoukankan      html  css  js  c++  java
  • Boost filessystem...

    CMakeList.txt:


     1 cmake_minimum_required(VERSION 3.8)
     2 project(Demo)
     3 
     4 set(CMAKE_CXX_STANDARD 11)
     5 
     6 set(SOURCE_FILES main.cpp)
     7 
     8 //需要添加filesystem组件
     9 find_package(Boost REQUIRED COMPONENTS system filesystem)
    10 
    11 if (Boost_FOUND)
    12     INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
    13     add_executable(Demo ${SOURCE_FILES})
    14     target_link_libraries(Demo ${Boost_LIBRARIES})
    15 endif ()
    16 
    17 find_package(Boost REQUIRED COMPONENTS system)

    boost::filesystem


    boost::filesystem库的核心类是path类,他屏蔽了不同文件系统的差异,使用了可移植的POSIX语法提供了通用的目录和路径表示,并且支持POSIX的符号链接

    boost::filesystem::path


    path的构造函数可接受char*类型和string类型的参数构造,也可以是一个字符串迭代范围,路径的分割符由constexpr preferred_separator定义,UNIX是正斜杠(/),WINDOWS是反斜杠(),C++中需要转义;

    path使用的是POSIX语法标准,使用正斜杠(/)来分割目录,(./)代表当前路径,(..)代表当前目录上层; 

    path类中基本实现了大部分文件属性操作,具体查看官方文档,以下只做了少部分测试

    基本方法:

     1 #include <iostream>
     2 #include <boost/filesystem.hpp>
     3 
     4 
     5 int
     6 main(int argc, char **argv)
     7 {
     8     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
     9     try
    10     {
    11         //unix
    12         boost::filesystem::path path1("./Demo/Demo.txt");
    13         //windows
    14         boost::filesystem::path path2("C:\Boost\Demo\include\");
    15 
    16         //空路径,可用empty()判断
    17         boost::filesystem::path path3;
    18         assert(path3.empty());
    19 
    20         //path构造时不会检查路径的合法性(可使用函数判断)
    21         boost::filesystem::path path4("asdwqdqdasd");
    22 
    23 
    24         boost::filesystem::path path5("/usr/local/include/");
    25         auto path6 = path5 / "boost/filesystem/";                    //path重载了operator/()方法可追加路径
    26         std::cout << path6 << std::endl;                             //path重载operator<<方法输出
    27         std::cout << path6.string() << std::endl;                    //返回string的方法,可用于C++中的fstream
    28         std::cout << path6.parent_path() << std::endl; //父路径
    29         std::cout << path6.filename() << std::endl; //文件
    30         std::cout << path6.stem() << std::endl; //不带扩展名的文件名
    31         std::cout << path6.extension() << std::endl; //扩展名
    32 
    33 
    34         //唯一两个可修改路径函数
    35         path6.replace_extension("ini");     //修改文件后缀名
    36         std::cout << path6 << std::endl;                    //"/usr/local/include/boost/filesystem/.ini"
    37         path6.remove_filename();            //移除文件名
    38         std::cout << path6 << std::endl;                    //"/usr/local/include/boost/filesystem"
    39 
    40 
    41         //path中有begin 和 end 迭代器,可以循环得出目录名
    42         for (auto &iter:path6)
    43         {
    44             std::cout << "[" << iter << "]" << std::endl;
    45         }
    46         /*["/"]
    47           ["usr"]
    48           ["local"]
    49           ["include"]
    50           ["boost"]
    51           ["filesystem"]*/
    52 
    53 
    54         ////                                     file_type                                        //
    55 ////--------------------------------------------------------------------------------------//
    56 //
    57 //        enum file_type
    58 //        {
    59 //            status_error,
    60 //#   ifndef BOOST_FILESYSTEM_NO_DEPRECATED
    61 //            status_unknown = status_error,
    62 //#   endif
    63 //            file_not_found,
    64 //            regular_file,
    65 //            directory_file,
    66 //            // the following may not apply to some operating systems or file systems
    67 //                    symlink_file,
    68 //            block_file,
    69 //            character_file,
    70 //            fifo_file,
    71 //            socket_file,
    72 //            reparse_file,  // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink
    73 //            type_unknown,  // file does exist, but isn't one of the above types or
    74 //            // we don't have strong enough permission to find its type
    75 //
    76 //            _detail_directory_symlink  // internal use only; never exposed to users
    77 //        };
    78 
    79         std::cout << boost::filesystem::status(path6).type() << std::endl;              //文件类型
    80         std::cout << boost::filesystem::symlink_status(path6).type() << std::endl;
    81         std::cout << boost::filesystem::directory_file << std::endl;
    82         std::cout << boost::filesystem::status(path6).permissions() << std::endl;      //文件的权限等级
    83 
    84 
    85     }
    86     catch (boost::filesystem::filesystem_error &e)
    87     {
    88         std::cout << e.path1() << std::endl;
    89         std::cout << e.path2() << std::endl;
    90         std::cout << e.what() << std::endl;
    91     }
    92 
    93 
    94     return 0;
    95 }
    96   

    查看磁盘和当前路径,修改文件时间(linux::touch)

     1 #include <iostream>
     2 #include <boost/filesystem.hpp>
     3 #include <boost/ratio.hpp>
     4 
     5 int
     6 main()
     7 {
     8     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
     9     try
    10     {
    11 
    12         boost::filesystem::path path("/Users/xuaidong/Desktop/test.txt");
    13         boost::filesystem::path path1("/Users/xuaidong");
    14         //进入(程序启动时)main函数时的路径
    15         std::cout << boost::filesystem::initial_path() << std::endl;
    16         //返回当前路径,和initial_path()都是返回绝对路径(完整路径)
    17         std::cout << boost::filesystem::current_path() << std::endl;
    18 
    19 
    20         assert(boost::filesystem::is_regular_file(path));
    21 
    22         //返回文件最后一次修改时间
    23         std::cout << boost::filesystem::last_write_time(path) << std::endl;
    24         //更改文件修改时间(linux touch)
    25         boost::filesystem::last_write_time(path, time(0));
    26         std::cout << boost::filesystem::last_write_time(path) << std::endl;
    27 
    28         //查看磁盘空间
    29 
    30         boost::filesystem::space_info sp = boost::filesystem::space(path);
    31         std::cout << "磁盘空间: " << sp.capacity / boost::giga::num << std::endl;
    32         std::cout << "磁盘可用空间: " << sp.free / boost::giga::num << std::endl;
    33         std::cout << "磁盘可用空间: " << sp.available / boost::giga::num << std::endl;
    34 
    35 
    36         std::cout << boost::filesystem::file_size(path) << std::endl;
    37 
    38 
    39     }
    40     catch (boost::filesystem::filesystem_error &e)
    41     {
    42 
    43         std::cout << e.path1() << std::endl;
    44         std::cout << e.path2() << std::endl;
    45         std::cout << e.what() << std::endl;
    46     }
    47 
    48 
    49     return 0;
    50 }
    51   

    创建目录,删除目录,拷贝文件

     1 #include <iostream>
     2 #include <boost/filesystem.hpp>
     3 #include <boost/ratio.hpp>
     4 
     5 int
     6 main(int argc, char **argv)
     7 {
     8     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
     9     try
    10     {
    11         boost::filesystem::path path("/Users/xuaidong/Desktop/ABABAB");
    12 
    13         //assert(boost::filesystem::is_regular_file(path));
    14         assert(boost::filesystem::is_directory(path));
    15 
    16         //删除空目录/文件
    17         //boost::filesystem::remove(path);
    18         //递归删除多个目录或者文件
    19         boost::filesystem::remove_all(path);
    20 
    21 
    22         //根据path创建一个目录
    23         boost::filesystem::create_directories(path);
    24         assert(boost::filesystem::exists(path));
    25         //拷贝文件到这个目录下
    26         boost::filesystem::copy_file("/Users/xuaidong/Desktop/Some.txt", path / "Some2.txt");
    27 
    28         //重命名
    29         boost::filesystem::rename(path/"Some2.txt",path/"Demo.txt");
    30 
    31         //创建多及目录
    32         boost::filesystem::create_directories(path/"Director1"/"Director2"/"Director3");
    33 
    34 
    35     }
    36     catch (boost::filesystem::filesystem_error &e)
    37     {
    38 
    39         std::cout << e.path1() << std::endl;
    40         std::cout << e.path2() << std::endl;
    41         std::cout << e.what() << std::endl;
    42     }
    43 
    44 
    45     return 0;
    46 }
    47   

    使用boost::filesystem::director_iterator迭代当前目录下文件(不向下层目录迭代),但是也可实现目录下层目录循环递归,其实boost也提供了boost::filesystem::recursive_directory_iterator向下递归而且遍历目录是可控制的(深度/浅度),且速度比递归的director_itertaor快

      1 #include <iostream>
      2 #include <boost/filesystem.hpp>
      3 #include <boost/ratio.hpp>
      4 
      5 void resource_direction(const boost::filesystem::path& path)
      6 {
      7     //递归文件目录下的所有文件路径
      8     boost::filesystem::directory_iterator end;
      9     for(boost::filesystem::directory_iterator begin(path);begin!=end;begin++)
     10     {
     11         //如果是目录继续向下解析
     12         if (boost::filesystem::is_directory(*begin))
     13             resource_direction(*begin);
     14         else
     15             std::cout<<*begin<<std::endl;
     16 
     17     }
     18 
     19 }
     20 
     21 
     22 int
     23 main(int argc, char **argv)
     24 {
     25     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
     26     try
     27     {
     28         boost::filesystem::path path("/Users/xuaidong/Desktop/");
     29         resource_direction(path);
     30 
     31     }
     32     catch (boost::filesystem::filesystem_error &e)
     33     {
     34 
     35         std::cout << e.path1() << std::endl;
     36         std::cout << e.path2() << std::endl;
     37         std::cout << e.what() << std::endl;
     38     }
     39 
     40 
     41     return 0;
     42 }
     43 
     44 
     45 
     46 //系统提供的文件目录遍历
     47 #include <iostream>
     48 #include <boost/filesystem.hpp>
     49 #include <boost/ratio.hpp>
     50 #include <map>
     51 #include <vector>
     52 #include <string>
     53 #include <memory>
     54 
     55 
     56 int
     57 main(int argc, char **argv)
     58 {
     59     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
     60     try
     61     {
     62         std::map<int64_t, std::shared_ptr<std::vector<std::string>>> dir_map;
     63         //boost深度遍历目录和浅度遍历
     64         //默认构造是尾迭代器
     65         boost::filesystem::recursive_directory_iterator end;
     66         for (boost::filesystem::recursive_directory_iterator iter("/Users/xuaidong/Desktop"); iter != end; iter++)
     67         {
     68             //std::cout << "directory_level: " << iter.level() << "file path: " << *iter << std::endl;
     69             if (boost::filesystem::is_directory(*iter))
     70             {
     71                 iter.no_push();
     72             }             //不深度便利
     73             //iter.pop() 退出当前目录的遍历
     74 
     75             auto &ptr = dir_map[iter.level()];
     76             if (!ptr)
     77                 ptr.reset(new std::vector<std::string>);
     78 
     79             ptr->push_back(iter->path().string());
     80 
     81         }
     82 
     83         for (auto &iter1:dir_map)
     84         {
     85             for (auto &iter2:*(iter1.second))
     86             {
     87                 std::cout << "directory_level: " << iter1.first << ", file path: " << iter2 << std::endl;
     88             }
     89         }
     90 
     91     }
     92     catch (boost::filesystem::filesystem_error &e)
     93     {
     94 
     95         std::cout << e.path1() << std::endl;
     96         std::cout << e.path2() << std::endl;
     97         std::cout << e.what() << std::endl;
     98     }
     99 
    100 
    101     return 0;
    102 }
    103   
    104   

    实例1:实现简单文件查找

     1 #include <iostream>
     2 #include <boost/filesystem.hpp>
     3 #include <boost/ratio.hpp>
     4 #include <boost/optional.hpp>
     5 
     6 //boost filesystem realize find file
     7 
     8 boost::optional<boost::filesystem::path> find_file(const boost::filesystem::path& path,const std::string& file)
     9 {
    10     typedef boost::optional<boost::filesystem::path> result_value;
    11     if (!boost::filesystem::exists(path)&&!boost::filesystem::is_directory(path))
    12         return result_value();
    13 
    14     //递归目录查找
    15     boost::filesystem::recursive_directory_iterator end;
    16     for(boost::filesystem::recursive_directory_iterator iter(path);iter!=end;++iter)
    17     {
    18         if (!boost::filesystem::is_directory(*iter)&&iter->path().filename()==file)
    19             return result_value(iter->path());
    20     }
    21 
    22     return result_value();
    23 }
    24 
    25 
    26 
    27 int
    28 main(int argc, char **argv)
    29 {
    30     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    31     try
    32     {
    33         auto path=find_file("/Users/xuaidong/Desktop/","application.cpp");
    34 
    35         if (path)
    36         {
    37             std::cout<<"CMakeLists.txt is here: "<<*path<<std::endl;
    38         }else
    39         {
    40             std::cout<<"CMakeLists.txt not to find"<<std::endl;
    41         }
    42 
    43 
    44 
    45     }
    46     catch (boost::filesystem::filesystem_error &e)
    47     {
    48 
    49         std::cout << e.path1() << std::endl;
    50         std::cout << e.path2() << std::endl;
    51         std::cout << e.what() << std::endl;
    52     }
    53 
    54 
    55     return 0;
    56 }
    57   

    实例2:利用boost::xpressive正则匹配实现模糊查找(只实现"*"匹配)

     1 #include <iostream>
     2 #include <string>
     3 #include <boost/filesystem.hpp>
     4 #include <boost/xpressive/xpressive.hpp>
     5 #include <boost/algorithm/string.hpp>
     6 
     7 //boost filesystem realize obscure find file
     8 
     9 std::vector<boost::filesystem::path>
    10 find_file(const boost::filesystem::path &path, const std::string &file)
    11 {
    12 
    13     //之后查找使用- -
    14     static boost::xpressive::sregex_compiler rc;         //正则表达式工厂
    15     if (!rc[file].regex_id())
    16     {
    17         std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\."), "*", ".*");
    18         rc[file] = rc.compile(str);
    19     }
    20 
    21 
    22     typedef std::vector<boost::filesystem::path> result_value;
    23     result_value v;
    24     if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path))
    25     {
    26         return v;
    27     }
    28 
    29     //递归目录查找
    30     boost::filesystem::recursive_directory_iterator end;
    31     for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter)
    32     {
    33         if (!boost::filesystem::is_directory(*iter) &&
    34             boost::xpressive::regex_match(iter->path().filename().string(), rc[file]))
    35         {
    36             v.push_back(iter->path());
    37         }
    38     }
    39 
    40     return v;
    41 }
    42 
    43 
    44 int
    45 main(int argc, char **argv)
    46 {
    47     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    48     try
    49     {
    50         auto path = find_file("/Users/xuaidong/Desktop/", "*.txt");
    51 
    52         for (auto &iter:path)
    53         {
    54             std::cout << "file match: " << iter << std::endl;
    55         }
    56 
    57 
    58     }
    59     catch (boost::filesystem::filesystem_error &e)
    60     {
    61 
    62         std::cout << e.path1() << std::endl;
    63         std::cout << e.path2() << std::endl;
    64         std::cout << e.what() << std::endl;
    65     }
    66 
    67 
    68     return 0;
    69 }
    70   

    实例3:实现目录文件拷贝(空目录也考了)

      1 #include <iostream>
      2 #include <string>
      3 #include <boost/filesystem.hpp>
      4 #include <boost/xpressive/xpressive.hpp>
      5 #include <boost/algorithm/string.hpp>
      6 #include <boost/progress.hpp>
      7 
      8 
      9 std::vector<boost::filesystem::path>
     10 find_file(const boost::filesystem::path &path, const std::string &file)
     11 {
     12 
     13     //之后查找使用- -
     14     static boost::xpressive::sregex_compiler rc;         //正则表达式工厂
     15     if (!rc[file].regex_id())
     16     {
     17         std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\."), "*", ".*");
     18         rc[file] = rc.compile(str);
     19     }
     20 
     21 
     22     typedef std::vector<boost::filesystem::path> result_value;
     23     result_value v;
     24     if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path))
     25     {
     26         return v;
     27     }
     28 
     29     //递归目录查找
     30     boost::filesystem::recursive_directory_iterator end;
     31     for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter)
     32     {
     33         if (boost::xpressive::regex_match(iter->path().filename().string(), rc[file]))
     34         {
     35             v.push_back(iter->path());
     36         }
     37     }
     38 
     39     return v;
     40 }
     41 
     42 
     43 std::size_t
     44 copy_files(
     45         const boost::filesystem::path &from_dir,
     46         const boost::filesystem::path &to_dir,
     47         const std::string &filename = "*"
     48 )
     49 {
     50     if (!boost::filesystem::exists(from_dir))
     51     {
     52         std::cout << "file not find" << std::endl;
     53         return -1;
     54     }
     55 
     56 
     57     std::cout << "prepare copy please wait....." << std::endl;
     58     auto vcontain = find_file(from_dir, filename);
     59 
     60     if (vcontain.empty())
     61     {
     62         std::cout << "file is empty" << std::endl;
     63         return -1;
     64     }
     65 
     66 
     67     boost::filesystem::path temp;
     68     boost::progress_display display(vcontain.size());
     69 
     70     for (auto &iter:vcontain)
     71     {
     72         temp = to_dir / iter.string().substr(from_dir.string().length());
     73         std::cout << "file: " << temp << std::endl;
     74         if (!boost::filesystem::exists(temp.parent_path()))
     75         {
     76             boost::filesystem::create_directories(temp.parent_path());
     77         }
     78 
     79         if(boost::filesystem::is_directory(iter))
     80         {
     81             boost::filesystem::create_directories(temp);
     82         }
     83         else{
     84             boost::filesystem::copy_file(iter, temp, boost::filesystem::copy_option::overwrite_if_exists);
     85         }
     86 
     87         ++display;
     88     }
     89 
     90     std::cout << vcontain.size() << " filed copyed" << std::endl;
     91 
     92     return vcontain.size();
     93 
     94 }
     95 
     96 
     97 int
     98 main(int argc, char **argv)
     99 {
    100     //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    101     try
    102     {
    103         copy_files("/Users/xuaidong/Desktop/Boost", "/Users/xuaidong/Desktop/Test");
    104 
    105 
    106     }
    107     catch (boost::filesystem::filesystem_error &e)
    108     {
    109 
    110         std::cout << e.path1() << std::endl;
    111         std::cout << e.path2() << std::endl;
    112         std::cout << e.what() << std::endl;
    113     }
    114 
    115 
    116 }
    117   
  • 相关阅读:
    【女农场主手记】漂亮地晕和扯淡地安全
    2008最新个人所得税计算公式
    oracle 字符集乱码解决 详细解释了oracle字符集的问题
    单反相机的传奇—佳能单反50年辉煌之路(连载三)
    单反相机的传奇—佳能单反50年辉煌之路(连载七)
    2009年5月重上涠洲岛,大吃海鲜
    单反相机的传奇—佳能单反50年辉煌之路(连载六)
    单反相机的传奇—佳能单反50年辉煌之路(连载八)
    单反相机的传奇—佳能单反50年辉煌之路(连载二)
    单反相机的传奇—佳能单反50年辉煌之路(连载十)
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7291682.html
Copyright © 2011-2022 走看看