C++在17版本的标准库中引入了一个filesystem库,用来处理文件路径,以及文件访问。很多编译器(比如Clang)对filesystem库的支持还不是很好。为了解决这个问题,可以临时使用boost::filesystem来替代。其实C++17标准中的filesystem库就是从boost::filesystem演进而来的,使用boost::filesystem有助于以后平滑演进到C++17的filesystem库。

boost(当前最新的版本是1.69.0)是一大堆库的集合,fiesystem只是其中的一个库。如果你还不了解boost,可以阅读它的上手文档:

boost::filesystem带有一个入门教程:

在macos上通过cmake使用boost

接下来介绍如何在macos上通过cmake的方式使用boost::filesystem。

首先,通过以下命令按照boost

brew install boost

接着需要在cmake的CMakeLists.txt中加入boost相关的部分:

find_package(Boost 1.69.0 REQUIRED COMPONENTS filesystem)

cmake对boost有很好的支持,上面的指令翻译如下:

  • find_package(Boost 1.69.0 查找系统的boost, 目标版本是1.69.0
  • REQUIRED COMPONENTS filesystem) COMPONENTS用来限定boost的filesystem模块,REQUIRED表明必须找到指定的模块,否则会出错

上面的find_package命令如果找到boost::filesystem,会在cmake中设置一些变量,比如Boost_LIBRARIES、Boost_INCLUDE_DIRS,我们需要在编译目标上使用这些变量。假设prog是编译目标,那么可以按照下面的方式让prog去链接相应的boost库、以及指定相应的boost头文件的目录:

target_link_libraries(prog PRIVATE ${Boost_LIBRARIES})
target_include_directories(prog PRIVATE ${Boost_INCLUDE_DIRS})

在你的cpp文件中,可以按下面的方式来包含boost::filesystem的头文件:

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

有一些地方需要解释以下:

  • BOOST_FILESYSTEM_NO_DEPRECATED,在包含boost::filesystem的头文件之前定义,表示避免使用其中的一些废弃的、和C++标准相差太远的功能
  • namespace fs = boost::filesystem;,给boost::filesystem这个命名空间取一个代号,如果以后切换到C++17标准的filesystem库之后,可以将其改为namespace fs = std::filesystem;,而从避免过多代码改动。

小结

本文介绍如何使用boost::filesystem(主要在macos上)。boost::filesystem或者C++17的filesystem的一个核心类是filesystem::path。这个类提供了跨平台的文件路径的操作,可以把文件路径转化为不同操作系统中的表示形式,如Linux中的/var/system或者windows中的C:\Program Files。同时filesystem::path还支持Unicode操作。但filesystem::path和其他语言所提供的文件路径处理功能还是有一定的差距,比如Python的os.path功能就比filesystem::path丰富不少。

其他参考