首页 技术 正文
技术 2022年11月16日
0 收藏 831 点赞 3,858 浏览 11423 个字

CMakeList.txt:


 cmake_minimum_required(VERSION 3.8)
project(Demo) set(CMAKE_CXX_STANDARD ) set(SOURCE_FILES main.cpp) //需要添加filesystem组件
find_package(Boost REQUIRED COMPONENTS system filesystem) if (Boost_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
add_executable(Demo ${SOURCE_FILES})
target_link_libraries(Demo ${Boost_LIBRARIES})
endif () 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类中基本实现了大部分文件属性操作,具体查看官方文档,以下只做了少部分测试

基本方法:

 #include <iostream>
#include <boost/filesystem.hpp> int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
//unix
boost::filesystem::path path1("./Demo/Demo.txt");
//windows
boost::filesystem::path path2("C:\\Boost\\Demo\\include\\"); //空路径,可用empty()判断
boost::filesystem::path path3;
assert(path3.empty()); //path构造时不会检查路径的合法性(可使用函数判断)
boost::filesystem::path path4("asdwqdqdasd"); boost::filesystem::path path5("/usr/local/include/");
auto path6 = path5 / "boost/filesystem/"; //path重载了operator/()方法可追加路径
std::cout << path6 << std::endl; //path重载operator<<方法输出
std::cout << path6.string() << std::endl; //返回string的方法,可用于C++中的fstream
std::cout << path6.parent_path() << std::endl; //父路径
std::cout << path6.filename() << std::endl; //文件
std::cout << path6.stem() << std::endl; //不带扩展名的文件名
std::cout << path6.extension() << std::endl; //扩展名 //唯一两个可修改路径函数
path6.replace_extension("ini"); //修改文件后缀名
std::cout << path6 << std::endl; //"/usr/local/include/boost/filesystem/.ini"
path6.remove_filename(); //移除文件名
std::cout << path6 << std::endl; //"/usr/local/include/boost/filesystem" //path中有begin 和 end 迭代器,可以循环得出目录名
for (auto &iter:path6)
{
std::cout << "[" << iter << "]" << std::endl;
}
/*["/"]
["usr"]
["local"]
["include"]
["boost"]
["filesystem"]*/ //// file_type //
////--------------------------------------------------------------------------------------//
//
// enum file_type
// {
// status_error,
//# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
// status_unknown = status_error,
//# endif
// file_not_found,
// regular_file,
// directory_file,
// // the following may not apply to some operating systems or file systems
// symlink_file,
// block_file,
// character_file,
// fifo_file,
// socket_file,
// reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink
// type_unknown, // file does exist, but isn't one of the above types or
// // we don't have strong enough permission to find its type
//
// _detail_directory_symlink // internal use only; never exposed to users
// }; std::cout << boost::filesystem::status(path6).type() << std::endl; //文件类型
std::cout << boost::filesystem::symlink_status(path6).type() << std::endl;
std::cout << boost::filesystem::directory_file << std::endl;
std::cout << boost::filesystem::status(path6).permissions() << std::endl; //文件的权限等级 }
catch (boost::filesystem::filesystem_error &e)
{
std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
}

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

 #include <iostream>
#include <boost/filesystem.hpp>
#include <boost/ratio.hpp> int
main()
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{ boost::filesystem::path path("/Users/xuaidong/Desktop/test.txt");
boost::filesystem::path path1("/Users/xuaidong");
//进入(程序启动时)main函数时的路径
std::cout << boost::filesystem::initial_path() << std::endl;
//返回当前路径,和initial_path()都是返回绝对路径(完整路径)
std::cout << boost::filesystem::current_path() << std::endl; assert(boost::filesystem::is_regular_file(path)); //返回文件最后一次修改时间
std::cout << boost::filesystem::last_write_time(path) << std::endl;
//更改文件修改时间(linux touch)
boost::filesystem::last_write_time(path, time());
std::cout << boost::filesystem::last_write_time(path) << std::endl; //查看磁盘空间 boost::filesystem::space_info sp = boost::filesystem::space(path);
std::cout << "磁盘空间: " << sp.capacity / boost::giga::num << std::endl;
std::cout << "磁盘可用空间: " << sp.free / boost::giga::num << std::endl;
std::cout << "磁盘可用空间: " << sp.available / boost::giga::num << std::endl; std::cout << boost::filesystem::file_size(path) << std::endl; }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
}

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

 #include <iostream>
#include <boost/filesystem.hpp>
#include <boost/ratio.hpp> int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
boost::filesystem::path path("/Users/xuaidong/Desktop/ABABAB"); //assert(boost::filesystem::is_regular_file(path));
assert(boost::filesystem::is_directory(path)); //删除空目录/文件
//boost::filesystem::remove(path);
//递归删除多个目录或者文件
boost::filesystem::remove_all(path); //根据path创建一个目录
boost::filesystem::create_directories(path);
assert(boost::filesystem::exists(path));
//拷贝文件到这个目录下
boost::filesystem::copy_file("/Users/xuaidong/Desktop/Some.txt", path / "Some2.txt"); //重命名
boost::filesystem::rename(path/"Some2.txt",path/"Demo.txt"); //创建多及目录
boost::filesystem::create_directories(path/"Director1"/"Director2"/"Director3"); }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
}

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

 #include <iostream>
#include <boost/filesystem.hpp>
#include <boost/ratio.hpp> void resource_direction(const boost::filesystem::path& path)
{
//递归文件目录下的所有文件路径
boost::filesystem::directory_iterator end;
for(boost::filesystem::directory_iterator begin(path);begin!=end;begin++)
{
//如果是目录继续向下解析
if (boost::filesystem::is_directory(*begin))
resource_direction(*begin);
else
std::cout<<*begin<<std::endl; } } int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
boost::filesystem::path path("/Users/xuaidong/Desktop/");
resource_direction(path); }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
} //系统提供的文件目录遍历
#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/ratio.hpp>
#include <map>
#include <vector>
#include <string>
#include <memory> int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
std::map<int64_t, std::shared_ptr<std::vector<std::string>>> dir_map;
//boost深度遍历目录和浅度遍历
//默认构造是尾迭代器
boost::filesystem::recursive_directory_iterator end;
for (boost::filesystem::recursive_directory_iterator iter("/Users/xuaidong/Desktop"); iter != end; iter++)
{
//std::cout << "directory_level: " << iter.level() << "file path: " << *iter << std::endl;
if (boost::filesystem::is_directory(*iter))
{
iter.no_push();
} //不深度便利
//iter.pop() 退出当前目录的遍历 auto &ptr = dir_map[iter.level()];
if (!ptr)
ptr.reset(new std::vector<std::string>); ptr->push_back(iter->path().string()); } for (auto &iter1:dir_map)
{
for (auto &iter2:*(iter1.second))
{
std::cout << "directory_level: " << iter1.first << ", file path: " << iter2 << std::endl;
}
} }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
}

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

 #include <iostream>
#include <boost/filesystem.hpp>
#include <boost/ratio.hpp>
#include <boost/optional.hpp> //boost filesystem realize find file boost::optional<boost::filesystem::path> find_file(const boost::filesystem::path& path,const std::string& file)
{
typedef boost::optional<boost::filesystem::path> result_value;
if (!boost::filesystem::exists(path)&&!boost::filesystem::is_directory(path))
return result_value(); //递归目录查找
boost::filesystem::recursive_directory_iterator end;
for(boost::filesystem::recursive_directory_iterator iter(path);iter!=end;++iter)
{
if (!boost::filesystem::is_directory(*iter)&&iter->path().filename()==file)
return result_value(iter->path());
} return result_value();
} int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
auto path=find_file("/Users/xuaidong/Desktop/","application.cpp"); if (path)
{
std::cout<<"CMakeLists.txt is here: "<<*path<<std::endl;
}else
{
std::cout<<"CMakeLists.txt not to find"<<std::endl;
} }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
}

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

 #include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/algorithm/string.hpp> //boost filesystem realize obscure find file std::vector<boost::filesystem::path>
find_file(const boost::filesystem::path &path, const std::string &file)
{ //之后查找使用- -
static boost::xpressive::sregex_compiler rc; //正则表达式工厂
if (!rc[file].regex_id())
{
std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\\."), "*", ".*");
rc[file] = rc.compile(str);
} typedef std::vector<boost::filesystem::path> result_value;
result_value v;
if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path))
{
return v;
} //递归目录查找
boost::filesystem::recursive_directory_iterator end;
for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter)
{
if (!boost::filesystem::is_directory(*iter) &&
boost::xpressive::regex_match(iter->path().filename().string(), rc[file]))
{
v.push_back(iter->path());
}
} return v;
} int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
auto path = find_file("/Users/xuaidong/Desktop/", "*.txt"); for (auto &iter:path)
{
std::cout << "file match: " << iter << std::endl;
} }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} return ;
}

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

 #include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/progress.hpp> std::vector<boost::filesystem::path>
find_file(const boost::filesystem::path &path, const std::string &file)
{ //之后查找使用- -
static boost::xpressive::sregex_compiler rc; //正则表达式工厂
if (!rc[file].regex_id())
{
std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\\."), "*", ".*");
rc[file] = rc.compile(str);
} typedef std::vector<boost::filesystem::path> result_value;
result_value v;
if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path))
{
return v;
} //递归目录查找
boost::filesystem::recursive_directory_iterator end;
for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter)
{
if (boost::xpressive::regex_match(iter->path().filename().string(), rc[file]))
{
v.push_back(iter->path());
}
} return v;
} std::size_t
copy_files(
const boost::filesystem::path &from_dir,
const boost::filesystem::path &to_dir,
const std::string &filename = "*"
)
{
if (!boost::filesystem::exists(from_dir))
{
std::cout << "file not find" << std::endl;
return -;
} std::cout << "prepare copy please wait....." << std::endl;
auto vcontain = find_file(from_dir, filename); if (vcontain.empty())
{
std::cout << "file is empty" << std::endl;
return -;
} boost::filesystem::path temp;
boost::progress_display display(vcontain.size()); for (auto &iter:vcontain)
{
temp = to_dir / iter.string().substr(from_dir.string().length());
std::cout << "file: " << temp << std::endl;
if (!boost::filesystem::exists(temp.parent_path()))
{
boost::filesystem::create_directories(temp.parent_path());
} if(boost::filesystem::is_directory(iter))
{
boost::filesystem::create_directories(temp);
}
else{
boost::filesystem::copy_file(iter, temp, boost::filesystem::copy_option::overwrite_if_exists);
} ++display;
} std::cout << vcontain.size() << " filed copyed" << std::endl; return vcontain.size(); } int
main(int argc, char **argv)
{
//因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
try
{
copy_files("/Users/xuaidong/Desktop/Boost", "/Users/xuaidong/Desktop/Test"); }
catch (boost::filesystem::filesystem_error &e)
{ std::cout << e.path1() << std::endl;
std::cout << e.path2() << std::endl;
std::cout << e.what() << std::endl;
} }
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,942
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,468
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,281
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,095
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,728
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,765