boost.png (6897 bytes) 文件系统库
版本 4
主页    教程    参考    常见问题解答    版本    可移植性    V4    V3 简介    V3 设计    不推荐使用    错误报告   

参考文档

目录

简介
定义
一致性
<boost/filesystem.hpp> 概览
错误报告
path
    path 转换
    path 转换为原格式
    path 转换为一般格式
    path 编码转换
    path 要求
    path 构造函数
    path 赋值
    path 追加
    path 拼接
    path 修改器
    path 原格式观察器
    path 一般格式观察器
    path 比较
    path 分解
    path 查询
    path 迭代器
    path 已弃用的函数
    path 非成员函数
    path 插入器和提取器
 filesystem_error
    filesystem_error 构造函数
    filesystem_error path1
    filesystem_error path2
    filesystem_error what

枚举 file_type
枚举 perms
file_status
    file_status 构造函数
    file_status-modifiers 观察器
    file_status-observers 修改器
directory_entry
    directory_entry 构造函数
    directory_entry 观察器
    directory_entry 修改器
directory_iterator
    directory_iterator 成员
recursive_directory_iterator
操作函数
     absolute
     canonical
     copy
     copy_directory
     copy_file
     copy_symlink
     create_directories
     create_directory
     create_hard_link
     create_symlink
     creation_time
     current_path
     exists
     equivalent
     file_size
     hard_link_count

     initial_path
     is_block_file
     is_character_file
     is_directory
     is_empty
     is_fifo
     is_other
     is_regular_file
     is_reparse_file
     is_socket
     is_symlink
     last_write_time
     permissions
     read_symlink
     relative
     remove
     remove_all
     rename
     resize_file
     space
     status
     status_known
     symlink_status
     system_complete
     temp_directory_path
     unique_path
     weakly_canonical
文件流
路径分解表
Windows 上的长路径和 \\?\ 命名空间前缀
致谢
参考
 

简介

本参考文档描述了 C++ 程序在涉及到文件系统(包括路径、常规文件和目录)时可能使用的组件。

一致性 [fs.conformance]

ISO/IEC 9945 一致性 [fs.conform.9945]

本参考文档中的一些行为是通过参考 ISO/IEC 9945 来指定的。实际如何实现此类行为并没有提及。

[注意:这是一个用于实现依赖于操作系统的行为的“好像”规则。实际上,实现通常会调用本机操作系统的 API。—结束注释]

建议实现提供 ISO/IEC 9945 定义的行为。实现应记录与 ISO/IEC 9945 定义的行为不同的任何行为。鼓励不支持精确的 ISO/IEC 9945 行为的实现尽可能提供接近 ISO/IEC 9945 行为的行为,但要受实际操作系统和文件系统的限制。如果某个实现无法提供任何合理的行为,该实现应以实现定义的方式报告错误。

[注意:此类错误可能通过以下方式报告:#error 指令、 static_assertfilesystem_error 异常、特殊返回值或其他方式。—结束注释]

实现不需要提供特定文件系统不支持的行为。

[示例:某些存储卡、照相机内存和软盘使用的 FAT 文件系统 不支持硬链接、符号链接等很多更高级文件系统支持的功能。实现只需要支持由主机操作系统支持的 FAT 功能。—结束示例]

在此参考中描述的函数的行为可能与其在存在文件系统竞争情况下的规范不同。不要求进行诊断。

如果文件系统竞争的可能性会使程序在调用此参考文档中描述的函数之前无法可靠地测试先决条件,则不会为该条件指定Requires。相反,该条件指定为Throws条件。

[注意:作为设计实践,当程序在调用函数之前检测到先决条件是不合理时,不会指定先决条件。——注意结束]

与操作系统相关的符合性 [fs.conform.os]

在此参考文档中指定某些行为与操作系统相关 ([fs.def.osdep])。取决于其实现的操作系统是由实现定义的。

允许实现依赖于操作系统模拟器,而不是实际操作系统。

[示例:某个实现使用 Cygwin,这是一种面向某些 Windows® 操作系统版本的 Linux® API 模拟器。该实现将 Cygwin 定义为其操作系统。用户可以参考 Cygwin 文档以找到操作系统相关行为的详细信息。——示例结束]

用户和符合性测试能够检测出此类实现是在 Cygwin 中运行的。如果实现将 Linux 或 Windows 定义为操作系统而不是 Cygwin,用户会误以为该实现是 Linux 或 Windows,并且符合性测试会失败,因为实际行为融合了这两者。

定义 [fs.definitions]

以下定义适用于整个参考文档

与操作系统相关的行为 [fs.def.osdep]

依赖于操作系统行为和特性的行为。请参阅 [fs.conform.os]。

文件 [fs.def.file]

可以写入、读取或同时写入和读取的对象。文件具有一些属性,包括类型。文件类型包括常规文件和目录。实现可能支持其他类型的文件,例如符号链接。

文件系统 [fs.def.filesystem]

文件集合及其某些属性。

文件名 [fs.def.filename]

文件名称。文件名 "."  和 ".."  具有特殊含义。文件名的以下特性与操作系统相关

路径 [fs.def.path]

一个序列的元素会确定文件在文件系统中的位置。这些元素有 root-nameopt root-directoryopt,以及一个可选的文件名序列。 [注意: pathname 是路径的具体展示。 —结束注]

绝对路径 [fs.def.absolute-path]

一种明确标识文件位置的路径,而无需提及额外的起始位置。路径的决定它是绝对路径的元素会根据不同的操作系统确定。

相对路径 [fs.def.relative-path]

一种不是绝对路径的路径,因此只会根据一个隐含的起始位置进行明确标识文件位置。路径的决定它是相对路径的元素会根据不同的操作系统确定。 [注意: 路径 "."".." 是相对路径。 —结束注]

规范路径 [fs.def.canonical-path]

没有符号连接元素以及没有 "."".." 元素的绝对路径。

pathname [fs.def.pathname]

表示路径名的一个字符字符串。路径名会根据通用路径名语法或一个操作系统相关的原生路径名格式进行格式化。

原生路径名格式 [fs.def.native]

由主机操作系统所接受的操作系统相关路径名格式。

常规形式 路径 [fs.def.normal]

没有冗余目录分隔符、当前目录 (dot) 或父目录 (dot-dot) 元素的路径。空路径的常规形式也是空路径。 [v3: 以不是根目录的 directory-separator 结尾的路径的常规形式是相同路径,后加一个当前目录 (dot) 元素]

连接 [fs.def.link]

将文件名与文件相关联的目录条目对象。在某些文件系统中,一些目录条目会将名称与相同文件相关联。

硬连接 [fs.def.hardlink]

一个现有文件的连接。某些文件系统支持多个硬连接到一个文件。如果文件的所有硬连接都被移除,文件本身将会被移除。

[注意: 硬连接可以看成是用于文件的共享所有权智能指针。 —结束注]

符号连接 [fs.def.symlink]

一种文件类型,当在路径名解析期间遇到文件时,文件储存在的字符串会用来修改路径名解析。

[注意: 符号连接可以看成指向文件的原始指针。如果指针所指向的文件不存在,则该符号连接被称为“悬空”符号连接。 —结束注]

文件系统竞用 [fs.def.race]

在文件系统中,多个线程、进程或计算机交错访问和修改同一对象时发生的条件。

通用路径名格式 [path.generic]

路径名
            root-name可选 root-directory可选 relative-path可选

root-name:
           
一个操作系统相关名称,用于识别绝对路径的起始位置。

[注意:许多操作系统将以两个目录分隔符字符开头的名称定义为root-name,该名称标识网络或其他资源位置。某些操作系统将字母后跟冒号定义为驱动器指定符,即root-name,该名称标识特定设备(例如,磁盘驱动器)。——结束注释]

root-directory
            directory-separator

relative-path
            filename
            relative-path directory-separator
            relative-path directory-separator filename

filename:
            name
           
"."
           
".."

preferred-separator:
           
一个操作系统相关的目录分隔符字符。可能是 "/" 的同义词。

directory-separator
            "/"
      "/"
directory-separator
            preferred-separator
            preferred-separator directory-separator

把多个连续的directory-separator字符视为一个directory-separator字符。

filename "." 被视为对当前目录的引用。filename ".." 被视为对父目录的引用。具体filename 可能对特定操作系统具有特殊意义。

与操作系统相关的示例(资料性)[fs.os.examples]

该参考文档中将某些特性指定为与操作系统相关。下表显示了将这些规范应用于使用 ISO/IEC 9945 或 Windows® 应用程序接口 (API) 的操作系统的示例。[脚注 1]

特性

部分

ISO/IEC 9945
 POSIX
® API

Windows® API

注释

path
 ::value_type

[class.path]

char

wchar_t

 

path::preferred
 _separator

[class.path]

'/'

L'\\' (单反斜杠)

 

path("/")
 .is_absolute()
path("c:/")
 .is_absolute()

[path
 .query]


true

false


false

true

 

path 参数在通用格式和本机格式之间的消除歧义

[path.arg
 .fmt.cvt]

不需要

不需要

对于这些操作系统,无需区分通用格式和本机格式。

path 参数格式转换

[path.arg
 .fmt.cvt]

不执行转换

不执行转换

通用格式已经适用于这些操作系统本身的 API 了。

path
 ("/cats/jane")
 .c_str()
path|
 ("/cats/jane/")
 .c_str()

[path.arg
 .fmt.cvt]



"/cats/jane"


"/cats/jane/"



L"/cats/jane"


L"/cats/jane/"

这些操作系统接受目录名和最终文件名之间的相同本机分隔符,因此无需执行格式转换。其他操作系统可能需要转换。

path本机格式观察者执行格式转换

[path.native
 .obs]

不执行转换

不执行转换

为了提高效率,无论操作系统如何,path对象都必须以本机格式存储路径名。

path通用格式观察者执行格式转换

[path
 .generic
 .obs]

不执行转换

反斜杠转换为斜杠

 

p.
 make_preferred()

[fs.path
 .modifiers]

不更改

斜杠转换为反斜杠

 

文件名中禁止使用的字符

[fs.def
 .filename]

0x00、'/'

0x00-0x1F、'"''*' '*''<''>''?''\\'(单个反斜杠)、'/''|'

许多操作系统禁止在文件名中使用 ASCII 控制字符 (0x00-0x1F)。

初始的 imbue 的path语言环境

[path
 .imbued
 .locale]

std::
  locale("")
[脚注 2]

实现提供的语言环境,如果AreFileApisANSI为真,则使用MultiByte
  ToWideChar
WideChar
  ToMultiByte
,代码页为CP_ACP;否则,代码页为CP_OEMCP[脚注 3]

Apple OS X®: 实现提供的语言环境,提供 UTF-8 codecvt切面。[脚注 4]

[脚注 1]OS X®和 Windows®是市售操作系统的示例。本信息提供给本文件用户以方便使用,并不代表 ISO 或 IEC 认可这些产品。

[脚注 2]基本原理:ISO C 将std::locale("")指定为“特定于语言环境的本机环境”,而 ISO/IEC 9945 称它“指定一个由实现定义的本机环境”。

[脚注 3]基本原理:这是 C 和 C++ 标准库函数使用窄字符字符串标识路径执行文件操作时的当前行为。更改此行为会令人惊讶,并与现有代码(尤其涉及用户输入的代码)产生差异。

[脚注 4]基本原理:供应商文档说“所有 BSD 系统功能都希望其字符串参数以 UTF-8 编码提供,而没有其他编码”。

头文件<boost/filesystem.hpp> 概要 [filesystem.synopsis]

namespace boost
{
  namespace filesystem
  {
    class path;

    bool lexicographical_compare(path::iterator first1, path::iterator last1,
      path::iterator first2, path::iterator last2);
    void swap(path& lhs, path& rhs) noexcept;
    std::size_t hash_value(const path& p);

    bool operator==(const path& lhs, const path& rhs);
    bool operator!=(const path& lhs, const path& rhs);
    bool operator< (const path& lhs, const path& rhs);
    bool operator<=(const path& lhs, const path& rhs);
    bool operator> (const path& lhs, const path& rhs);
    bool operator>=(const path& lhs, const path& rhs);

    path operator/ (const path& lhs, const path& rhs);

    std::ostream&  operator<<( std::ostream& os, const path& p );
    std::wostream& operator<<( std::wostream& os, const path& p );
    std::istream&  operator>>( std::istream& is, path& p );
    std::wistream& operator>>( std::wistream& is, path& p )

    class filesystem_error;
    class directory_entry;

    class directory_iterator;

    // enable c++11 range-based for statements
    const directory_iterator& begin(const directory_iterator& iter);
    directory_iterator end(const directory_iterator&);


    // enable BOOST_FOREACH
    directory_iterator& range_begin(directory_iterator& iter);
    directory_iterator range_begin(const directory_iterator& iter);
    directory_iterator range_end(const directory_iterator&);

    class recursive_directory_iterator;

    // enable c++11 range-based for statements
    const recursive_directory_iterator&
      begin(const recursive_directory_iterator& iter);
    recursive_directory_iterator
      end(const recursive_directory_iterator&);


    // enable BOOST_FOREACH
    recursive_directory_iterator&
      range_begin(recursive_directory_iterator& iter);
    recursive_directory_iterator
      range_begin(const recursive_directory_iterator& iter);
    recursive_directory_iterator
      range_end(const recursive_directory_iterator&);

    enum file_type
    {
      status_error, file_not_found, regular_file, directory_file,
      symlink_file, block_file, character_file, fifo_file, socket_file,
      reparse_file, type_unknown
    };

    enum perms
    {
      no_perms,
      owner_read, owner_write, owner_exe, owner_all,
      group_read, group_write, group_exe, group_all,
      others_read, others_write, others_exe, others_all, all_all,
      set_uid_on_exe, set_gid_on_exe, sticky_bit,
      perms_mask, perms_not_known,
      add_perms, remove_perms, symlink_perms
    };

    class file_status;

    struct space_info  // returned by space function
    {
      uintmax_t capacity;
      uintmax_t free;
      uintmax_t available; // free space available to non-privileged process
    };

    enum class copy_options
    {
      none = 0u,
      // copy_file options
      skip_existing,
      overwrite_existing,
      update_existing,
      synchronize_data,
      synchronize,
      ignore_attribute_errors,
      // copy options
      recursive,
      copy_symlinks,
      skip_symlinks,
      directories_only,
      create_symlinks,
      create_hard_links
    };

    enum class directory_options
    {
      none = 0u,
      skip_permission_denied,
      follow_directory_symlink,
      pop_on_error
    };

    // operational functions

    path         absolute(const path& p, const path& base=current_path());
    path         absolute(const path& p, system::error_code& ec);
    path         absolute(const path& p, const path& base,
                   system::error_code& ec);

    path         canonical(const path& p, const path& base = current_path());
    path         canonical(const path& p, system::error_code& ec);
    path         canonical(const path& p, const path& base,
                   system::error_code& ec);

    void         copy(const path& from, const path& to);
    void         copy(const path& from, const path& to,
                   system::error_code& ec);
    void         copy(const path& from, const path& to,
                   copy_options options);
    void         copy(const path& from, const path& to,
                   copy_options options, system::error_code& ec);

    bool         copy_file(const path& from, const path& to);
    bool         copy_file(const path& from, const path& to,
                   system::error_code& ec);
    bool         copy_file(const path& from, const path& to,
                   copy_options options);
    bool         copy_file(const path& from, const path& to,
                   copy_options options, system::error_code& ec);

    void         copy_symlink(const path& existing_symlink,
                   const path& new_symlink);
    void         copy_symlink(const path& existing_symlink,
                   const path& new_symlink, system::error_code& ec);

    bool         create_directories(const path& p);
    bool         create_directories(const path& p,
                   system::error_code& ec);

    bool         create_directory(const path& p);
    bool         create_directory(const path& p, system::error_code& ec);
    bool         create_directory(const path& p, const path& existing);
    bool         create_directory(const path& p, const path& existing, system::error_code& ec);

    void         create_directory_symlink(const path& to,
                   const path& new_symlink);
    void         create_directory_symlink(const path& to,
                   const path& new_symlink, system::error_code& ec);

    void         create_hard_link(const path& to, const path& new_hard_link);
    void         create_hard_link(const path& to, const path& new_hard_link,
                                  system::error_code& ec);

    void         create_symlink(const path& to, const path& new_symlink);
    void         create_symlink(const path& to, const path& new_symlink,
                                system::error_code& ec);

    std::time_t  creation_time(const path& p);
    std::time_t  creation_time(const path& p, system::error_code& ec);

    path         current_path();
    path         current_path(system::error_code& ec);
    void         current_path(const path& p);
    void         current_path(const path& p, system::error_code& ec);

    bool         exists(file_status s) noexcept;
    bool         exists(const path& p);
    bool         exists(const path& p, system::error_code& ec) noexcept;

    bool         equivalent(const path& p1, const path& p2);
    bool         equivalent(const path& p1, const path& p2,
                   system::error_code& ec);

    uintmax_t    file_size(const path& p);
    uintmax_t    file_size(const path& p, system::error_code& ec);

    uintmax_t    hard_link_count(const path& p);
    uintmax_t    hard_link_count(const path& p, system::error_code& ec);

    const path&  initial_path();
    const path&  initial_path(system::error_code& ec);

    bool         is_block_file(file_status s) noexcept;
    bool         is_block_file(const path& p);
    bool         is_block_file(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_character_file(file_status s) noexcept;
    bool         is_character_file(const path& p);
    bool         is_character_file(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_directory(file_status s) noexcept;
    bool         is_directory(const path& p);
    bool         is_directory(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_empty(const path& p);
    bool         is_empty(const path& p, system::error_code& ec);

    bool         is_fifo(file_status s) noexcept;
    bool         is_fifo(const path& p);
    bool         is_fifo(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_other(file_status s) noexcept;
    bool         is_other(const path& p,);
    bool         is_other(const path& p, system::error_code& ec) noexcept;

    bool         is_regular_file(file_status s) noexcept;
    bool         is_regular_file(const path& p);
    bool         is_regular_file(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_reparse_file(file_status s) noexcept;
    bool         is_reparse_file(const path& p);
    bool         is_reparse_file(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_socket(file_status s) noexcept;
    bool         is_socket(const path& p);
    bool         is_socket(const path& p,
                   system::error_code& ec) noexcept;

    bool         is_symlink(file_status s noexcept);
    bool         is_symlink(const path& p);
    bool         is_symlink(const path& p, system::error_code& ec) noexcept;

    std::time_t  last_write_time(const path& p);
    std::time_t  last_write_time(const path& p, system::error_code& ec);
    void         last_write_time(const path& p, const std::time_t new_time);
    void         last_write_time(const path& p, const std::time_t new_time,
                                 system::error_code& ec);

    path         read_symlink(const path& p);
    path         read_symlink(const path& p, system::error_code& ec);

    path         relative(const path& p, system::error_code& ec);
    path         relative(const path& p, const path& base=current_path());
    path         relative(const path& p,
                     const path& base, system::error_code& ec);

    bool         remove(const path& p);
    bool         remove(const path& p, system::error_code& ec);

    uintmax_t    remove_all(const path& p);
    uintmax_t    remove_all(const path& p, system::error_code& ec);

    void         rename(const path& from, const path& to);
    void         rename(const path& from, const path& to,
                   system::error_code& ec);

    void         resize_file(const path& p, uintmax_t size);
    void         resize_file(const path& p, uintmax_t size,
                   system::error_code& ec);

    space_info   space(const path& p);
    space_info   space(const path& p, system::error_code& ec);

    file_status  status(const path& p);
    file_status  status(const path& p, system::error_code& ec) noexcept;

    bool         status_known(file_status s) noexcept;

    file_status  symlink_status(const path& p);
    file_status  symlink_status(const path& p,
                   system::error_code& ec) noexcept;

    path         system_complete(const path& p);
    path         system_complete(const path& p, system::error_code& ec);

    path         temp_directory_path();
    path         temp_directory_path(system::error_code& ec);

    path         unique_path(const path& model="%%%%-%%%%-%%%%-%%%%");
    path         unique_path(system::error_code& ec);
    path         unique_path(const path& model, system::error_code& ec);

    path         weakly_canonical(const path& p, const path& base=current_path());
    path         weakly_canonical(const path& p, system::error_code& ec);
    path         weakly_canonical(const path& p, const path& base,
                   system::error_code& ec);

  }  // namespace filesystem
}  // namespace boost

错误报告 [fs.err.report]

文件系统库函数通常有两种重载形式,一种是抛出异常以报告文件系统错误,另一种是设置一个error_code

[注意: 这支持两种常见用例

—结束注释]

以下函数没有 type 为 system::error_code& 的参数,会以如下方式报告错误,除非另有指定

以下函数具有 type 为 system::error_code& 的参数,会以如下方式报告错误,除非另有指定

path [class.path]

path 的一个对象表示一个 路径,并包含一个 路径名。此类对象只关注路径的词汇和语法方面。这个路径不一定会存在于外部存储设备中,且路径名不一定会对当前操作系统或特定文件系统有效。

namespace boost
{
  namespace filesystem
  {
      class path
      {
      public:
        typedef see below                                    value_type;
        typedef std::basic_string<value_type>                string_type;
        typedef std::codecvt<wchar_t, char, std::mbstate_t>  codecvt_type;
        constexpr value_type                                 dot;
        constexpr value_type                                 separator;
        constexpr value_type                                 preferred_separator;

        // constructors and destructor
        path();
        path(const path& p);
        path(path&& p) noexcept;

        template <class Source>
          path(Source const& source, const codecvt_type& cvt=codecvt());

        template <class InputIterator>
          path(InputIterator begin, InputIterator end,
            const codecvt_type& cvt=codecvt());

       ~path();

        // assignments
        path& operator=(const path& p);
        path& operator=(path&& p) noexcept;

        template <class Source>
          path& operator=(Source const& source);

        path& assign(const path& p);
        path& assign(path&& p) noexcept;
        template <class Source>
          path& assign(Source const& source,
            const codecvt_type& cvt=codecvt())

        template <class InputIterator>
          path& assign(InputIterator begin, InputIterator end,
            const codecvt_type& cvt=codecvt());

        // appends
        path& operator/=(const path& p);

        template <class Source>
          path& operator/=(Source const& source);

        path& append(const path& x);
        template <class Source>
          path& append(Source const& source,
            const codecvt_type& cvt=codecvt());

        template <class InputIterator>
          path& append(InputIterator begin, InputIterator end,
            const codecvt_type& cvt=codecvt());

        // concatenation
        path& operator+=(const path& x);
        template <class Source>
          path& operator+=(Source const& source);
        path& operator+=(value_type x);
        template <class CharT>
          path& operator+=(CharT x);

        path& concat(const path& x);
        template <class Source>
          path& concat(Source const& x,
            const codecvt_type& cvt=codecvt());
        template <class InputIterator>
          path& concat(InputIterator begin, InputIterator end,
            const codecvt_type& cvt=codecvt());

        // modifiers
        void  clear();
        path& make_preferred();
        path& remove_filename();
        path& remove_filename_and_trailing_separators();
        path& replace_filename(const path& replacement);
        path& replace_extension(const path& new_extension = path());
        void  swap(path& rhs) noexcept;

        // lexical operations
        path lexically_normal() const;
        path lexically_relative(const path& base) const;
        path lexically_proximate(const path& base) const;

        // native format observers
        const string_type&  native() const noexcept;  // native format, encoding
        const value_type*   c_str() const noexcept;   // native().c_str()
        string_type::size_type size() const noexcept; // native().size()

        template <class String>
          String  string(const codecvt_type& cvt=codecvt()) const;
        string    string(const codecvt_type& cvt=codecvt()) const;
        wstring   wstring(const codecvt_type& cvt=codecvt()) const;

        // generic format observers
        template <class String>
          String  generic_string() const;

        string    generic_string(const codecvt_type& cvt=codecvt()) const;
        wstring   generic_wstring(const codecvt_type& cvt=codecvt()) const;

        // compare
        int   compare(const path& p) const noexcept;
        int   compare(const std::string& s) const;
        int   compare(const value_type* s) const;

        // decomposition
        path  root_name() const;
        path  root_directory() const;
        path  root_path() const;
        path  relative_path() const;
        path  parent_path() const;
        path  filename() const;
        path  stem() const;
        path  extension() const;

        // query
        bool empty() const;
        bool filename_is_dot() const;
        bool filename_is_dot_dot() const;
        bool has_root_name() const;
        bool has_root_directory() const;
        bool has_root_path() const;
        bool has_relative_path() const;
        bool has_parent_path() const;
        bool has_filename() const;
        bool has_stem() const;
        bool has_extension() const;
        bool is_absolute() const;
        bool is_relative() const;

        // iterators
        class iterator;
        typedef iterator const_iterator;
        class reverse_iterator;
        typedef reverse_iterator const_reverse_iterator;

        iterator begin() const;
        iterator end() const;
        reverse_iterator rbegin() const;
        reverse_iterator rend() const;

        // imbued locale
        static std::locale imbue(const std::locale& loc);
        static const codecvt_type & codecvt();

      private:
        string_type pathname;  // exposition only
      };

  }  // namespace filesystem
}  // namespace boost

value_type 对操作系统用来表示路径名的字符类型进行typedef

path 使用注意事项 [path.usage]

多线程注意事项

文件系统库函数并不针对数据竞争进行保护。[修改一个在多线程之间共享的文件系统库类型的对象会引发未定义行为,除非该类型的对象被明确指定为在没有数据竞争的情况下可以共享或者用户提供了锁定机制。—结束注释] [注意: 因此,文件系统库的行为就像它属于标准库的一部分,且 C++ 标准 17.6.4.10 共享对象和库 [res.on.objects] 也适用。  —结束注释]

Windows 注意事项

至少到 2012 版本的 Visual C++ 没有使用 C++11 风格的静态初始化锁定,因此 path::codecvt() 的初始化可以触发竞争,如果从不同线程调用 path::imbue() 也可能会触发。一个变通办法是调用

path::codecvt();  // 确保 VC++ 不会在初始化过程中发生竞争。

在启动任何其他线程之前,在主线程中。 [注意: Filesystem 实现执行锁定的显式修复不起作用,因为 Microsoft 编译器存在不相关的其他问题;对于静态链接,运行时尝试在 main() 开始之前进行初始化,但在那时不允许操作系统锁定调用。  —结束注释]

POSIX 问题

在使用环境变量确定路径编码的 POSIX 系统(例如 Linux,但不包括 Mac OS X)上,Filesystem 库初始化可能会抛出一个异常。这发生在 `std::locale("")` 抛出异常时,因为 LANG 等环境变量被设为无效值,所以这会影响 `std::locale("")` 的任何用途,而不仅仅是 Filesystem 库。Filesystem 采用惰性初始化,所以只有当需要有效的 `std::locale("")` 时才会抛出异常,而且异常会在 `main()` 开始后抛出。

与其一直等到某个 Filesystem 库函数的调用意外触发异常(当它调用 `path::codecvt()` 时),需要对环境变量问题具有高度鲁棒性的程序不妨在尝试块内预先调用 `std::locale("")`、捕获异常以及诊断或修复无效环境变量。

path 转换 [path.cvt]

path 参数转换 [path.arg.cvt]

path 参数格式转换 [path.arg.fmt.cvt]

接受表示路径的字符序列的成员函数参数可以使用 通用路径名格式本机路径名格式。如果此类参数采用通用格式并且通用格式不能被操作系统接受为本机路径,则在处理参数时应进行本机格式转换。请参阅 [fs.os.examples]

[注意: 根据操作系统,实现可能没有明确的方法始终能够区分本机格式和通用格式参数。这是设计使然,因为它简化了那些不要求消除歧义的操作系统的用法。如果实现遇到需要消除歧义的操作系统,则实现可以定义扩展来区分格式。—结束注释]

如果本机格式要求以不同于目录路径的方式格式化普通文件的路径,那么在最后一个元素是分隔符时,应将路径视为目录路径,否则应将其视为普通文件路径。

path 参数编码转换 [path.arg.encoding.cvt]

对于接受表示路径的字符序列的成员函数参数,如果参数的值类型不是 `value_type`,并且一个值类型是 `char` 而另一个是 `wchar_t`,则应由 `path::codecvt()` 平面进行 `value_type` 转换。([path.imbued.locale]).

path 转换至通用格式 [fs.cvt.to.generic]

通用格式观察器 函数将返回根据通用路径名格式使用“首选分隔符”格式化的字符串。请参阅 [fs.os.examples]

path 要求 [path.req]

指定为 InputIterator 的模板参数需要满足 C++ 标准库 InputIterator 兼容迭代器的要求。迭代器的值类型需要是以下之一:charwchar_t。统称为这些类型受支持的路径字符类型。

指定为 Source 的模板参数需要是以下之一

path 构造函数 [path.construct]

template <class Source>
path(Source const& source, const codecvt_type& cvt=codecvt());
template <class InputIterator>
path(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());

作用:pathnamesource 的内容 [begin,end) 存储在中,在需要时转换格式和编码 ([path.arg.convert])。

path 赋值 [path.assign]

path& operator=(const path& p);
path& operator=(path&& p) noexcept;
template <class Source>
path& operator=(Source const& source);
path& assign(const path& p);
path& assign(path&& p) noexcept;
template <class Source>
path& assign(Source const& source, const codecvt_type& cvt=codecvt());
template <class InputIterator>
path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());

作用:pathnamesourcep 的内容 [begin,end) 存储在,在需要时转换格式和编码 ([path.arg.convert])。

返回: *this

path 追加 [path.append]

追加操作使用 operator/= 来表示所需时追加“首选分隔符”的语义效果。

path& operator/=(const path& p);
path& append(const path& p);

效果

v3: 追加 path::preferred_separatorpathname,在需要时转换格式和编码 ([path.arg.convert]),除非

然后将 p.native() 追加至 pathname

v4: 如果 p.is_absolute() || (p.has_root_name() && p.root_name() != root_name()),将 p 赋值给 *this。否则,修改 *this,如同以下步骤

[注释:路径是绝对路径还是相对路径取决于目标操作系统的约定。因此,对于某些路径,追加操作的结果对于不同的操作系统而言可能不同。例如,对于 POSIX 系统,path("//net/foo") / "/bar"的结果为"/bar",而对于 Windows,结果为"//net/foo/bar",因为"/bar"对于 POSIX 系统是绝对路径,但对于 Windows 不是。若要实现可移植行为,请避免附加非空根路径的路径。注释结束]

返回: *this

template <class Source>
path& operator/=(Source const & source);
template <class Source>
path& append(Source const & source, const codecvt_type& cvt=codecvt());
template <class InputIterator>
path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());

效果

就像append(path(args)),其中args是传递给操作的参数列表。

返回: *this

path连接 [path.concat]

path& operator+=(const path& p);
path& operator+=(value_type x);
template <class Source>
path& operator+=(Source const& source);
template <class CharT>
path& operator+=(CharT x);
path& concat(const path& p);
template <class Source>
path& concat(Source const& source, const codecvt_type& cvt=codecvt());
template <class InputIterator>
path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());

后置条件: native() == prior_native + effective-argument,其中prior_native是在调用operator+=之前native(),而effective-argument

如果effective-argument的值类型不是path::value_type,则会首先转换实际参数或参数范围,以便使effective-argument的值类型变为path::value_type

返回: *this

path修改器 [path.modifiers]

void clear();

后置条件: this->empty()为真。

path& make_preferred();

影响:目录分隔符转换为首选分隔符。请参见 [fs.os.examples]。

返回值: *this

path& remove_filename();

影响: v3:就像*this = parent_path();

[注释:需要此函数才能高效实现directory_iterator。将其公开以便允许其他用途。实际实现可能比*this = parent_path()高效得多。注释结束]

v4:删除filename()路径元素。

[注释:v3不同,不会删除尾部目录分隔符。注释结束]

返回值: *this

path& remove_filename_and_trailing_separators();

影响:就像*this = parent_path();

[注释:此函数类似于v3中的path::remove_filename,但也可用于v4注释结束]

返回值: *this

path& replace_filename(const path& replacement);

影响:就像remove_filename().append(replacement);

返回值: *this

path& replace_extension(const path& new_extension = path());

效果

返回值: *this

void swap(path& rhs) noexcept;

影响:交换两个路径中的内容。

复杂度:常量时间。

path词法操作 [path.lex.ops]

path lexically_normal() const;

概述:返回已删除冗余的当前目录(句点)、父目录(双句点)和目录分隔符*this

返回值:普通形式内的*this

备注:使用operator/=组合返回路径。

[示例:

std::cout << path("foo/./bar/..").lexically_normal() << std::endl;    // outputs "foo"
std::cout << path("foo/.///bar/../").lexically_normal() << std::endl; // v3: outputs "foo/."
                                                                      // v4: outputs "foo/"

在 Windows 系统中,返回路径的“目录分隔符”为反斜杠而非斜杠,但不会影响path 相等性 —示例结束]

path lexically_relative(const path& base) const;

概览:返回相对于base*this。将空或相同路径视为特殊情况,而非错误。不会解析符号链接。不会先对*thisbase 进行规范化。

备注:使用std::mismatch(begin(), end(), base.begin(), base.end())确定*thisbase 中不匹配的第一个元素。使用operator==确定元素是否匹配。

返回

[示例:

assert(path("/a/d").lexically_relative("/a/b/c") == "../../d");
assert(path("/a/b/c").lexically_relative("/a/d") == "../b/c");
assert(path("a/b/c").lexically_relative("a") == "b/c");
assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
assert(path("a/b/c").lexically_relative("a/b/c") == ".");
assert(path("a/b").lexically_relative("c/d") == "");

上述断言均会成功。 在 Windows 系统中,返回路径的“目录分隔符”为反斜杠而非正斜杠,但不会影响path 相等性。 —示例结束]

[注意:如果需要符号链接后续语义,请使用操作函数 relative  —注释结束]

[注意:如果需要 规范化 来确保元素匹配一致,请对*thisbase 或两者应用 lexically_normal()—注释结束]

path lexically_proximate(const path& base) const;

返回:如果lexically_relative(base)返回非空路径,则返回该路径。否则,返回*this

[注意:如果需要符号链接后续语义,请使用操作函数 relative  —注释结束]

[注意:如果需要 规范化 来确保元素匹配一致,请对*thisbase 或两者应用 lexically_normal()—注释结束]

path 本机格式观察器 [path.native.obs]

由所有本机格式观察器返回的字符串均为 本机路径名格式

const string_type& native() const noexcept;

返回:pathname

const value_type* c_str() const noexcept;

返回:pathname.c_str()

string_type::size_type size() const noexcept;

返回:pathname.size()

template <class String>
String string(const codecvt_type& cvt=codecvt()) const;

返回:pathname

备注:如果string_type是不同于String的类型,则转换由cvt执行。

string string(const codecvt_type& cvt=codecvt()) const;
wstring wstring(const codecvt_type& cvt=codecvt()) const;

返回:pathname

备注:如果string_type是不同于函数返回类型的类型,则转换由cvt执行。

path 通用格式观察器 [path.generic.obs]

所有通用的格式观察者返回的字符串都是 通用路径名格式。返回的字符串使用单正斜杠 ('/') 作为目录分隔符。

template <class String>
String generic_string(const codecvt_type& cvt=codecvt()) const;

返回:pathname

备注:如果string_type是不同于String的类型,则转换由cvt执行。

string generic_string(const codecvt_type& cvt=codecvt()) const;
wstring generic_wstring(const codecvt_type& cvt=codecvt()) const;

返回:pathname

备注:如果string_type是不同于函数返回类型的类型,则转换由cvt执行。

path 比较 [path.compare]

int compare(const path& p) const noexcept;

返回: 如果 *this 的元素小于 p 的元素,则返回小于 0 的值,否则如果 *this 的元素大于 p 的元素,则返回大于 0 的值,否则返回 0。

备注:元素的判断方法如下:对于 *thisp,迭代半开范围 [begin(), end())。

int compare(const std::string& s) const

返回: compare(path(s))

int compare(const value_type* s) const

返回: compare(path(s))

path 分解 [path.decompose]

有关分解函数返回的值示例,请参见 路径分解表教程 也可能会有所帮助。

path root_name() const;

返回: 如果 pathname 包含 根名称,则返回 根名称,否则返回 path()

path root_directory() const;

返回: 如果 pathname 包含 根目录,则返回 根目录,否则返回 path()

如果 根目录斜杠名称 组成,则返回的字符串中不包含 斜杠

path root_path() const;

返回: root_name() / root_directory()

path relative_path() const;

返回: 如果 !empty(),则从 根路径 后的第一个 文件名 开始,由 pathname 组成的 path。否则返回 path()

path parent_path() const;

返回: (empty() || begin() == --end()) ? path() : pp,其中 pp 是构造的,方法是从一个空的 path 开始,并对范围 begin()--end() 中的每个元素依次应用 operator/=

[示例:

std::cout << path("/foo/bar.txt").parent_path(); // outputs "/foo"
std::cout << path("/foo/bar").parent_path();     // outputs "/foo"
std::cout << path("/foo/bar/").parent_path();    // outputs "/foo/bar"
std::cout << path("/").parent_path();            // outputs ""
std::cout << path(".").parent_path();            // outputs ""
std::cout << path("..").parent_path();           // outputs ""

有关“/foo/bar/”示例不输出“/foo”的原因,请参阅 正向遍历顺序 列表中的最后一个项目符号。

—end example]

path filename() const;

返回: v3: empty() ? path() : *--end()
v4: *this == root_path() ? path() : *--end()

[示例:

std::cout << path("/foo/bar.txt").filename(); // outputs "bar.txt"
std::cout << path("/foo/bar").filename();     // outputs "bar"
std::cout << path("/foo/bar/").filename();    // v3 outputs "."
                                              // v4 outputs ""
std::cout << path("/").filename();            // v3 outputs "/"
                                              // v4 outputs ""
std::cout << path(".").filename();            // outputs "."
std::cout << path("..").filename();           // outputs ".."

有关“/foo/bar/”示例不输出“bar”的原因,请参阅 正向遍历顺序 列表中的最后一个项目符号。

—end example]

path stem() const;

返回: 如果 p.filename() 不包含圆点,只包含一个或两个圆点,[自 v4 起:或仅包含一个圆点作为初始字符,] 返回 p.filename()。否则,返回 p.filename() 的子字符串,从其开头开始,到最后一个圆点结束(不包括圆点)。

[示例:

std::cout << path("/foo/bar.txt").stem() << '\n'; // outputs "bar"
std::cout << path(".hidden").stem() << '\n';      // v3 outputs ""
                                                  // v4 outputs ".hidden"
path p = "foo.bar.baz.tar";
for (; !p.extension().empty(); p = p.stem())
  std::cout << p.extension() << '\n';
  // outputs: .tar
  //          .baz
  //          .bar

—end example]

path extension() const;

返回: p.filename() 中不包含在 p.stem() 中的子字符串。

备注:允许实现为在扩展名中追加其他元素(如备用数据流或分区数据集名称)的文件系统定义其他行为,但不是必需的。

[示例:

std::cout << path("/foo/bar.txt").extension(); // outputs ".txt"

—end example]

[注意: 该返回值中包含点,以便能够区分没有扩展名和空扩展名。有关更详细的理由,请参阅 https://lists.boost.org/Archives/boost/2010/02/162028.php。  —结束注意]

path 查询 [path.query]

bool empty() const;

返回: m_pathname.empty()

bool filename_is_dot() const;

返回: filename() == path(".")

[示例:

std::cout << path(".").filename_is_dot();     // outputs 1
std::cout << path("/.").filename_is_dot();    // outputs 1
std::cout << path("foo/.").filename_is_dot(); // outputs 1
std::cout << path("foo/").filename_is_dot();  // v3 outputs 1, v4 outputs 0
std::cout << path("/").filename_is_dot();     // outputs 0
std::cout << path("/foo").filename_is_dot();  // outputs 0
std::cout << path("/foo.").filename_is_dot(); // outputs 0
std::cout << path("..").filename_is_dot();    // outputs 0

请参阅 顺序遍历顺序 列表中的最后一个项目符号项,了解为什么 path("foo/").filename()v3 中是点文件名。

—end example]

bool filename_is_dot_dot() const;

返回: filename() == path("..")

bool has_root_path() const;

返回: !root_path().empty()

bool has_root_name() const;

返回: !root_name().empty()

bool has_root_directory() const;

返回: !root_directory().empty()

bool has_relative_path() const;

返回: !relative_path().empty()

bool has_parent_path() const;

返回: !parent_path().empty()

bool has_filename() const;

返回: !filename().empty()

bool has_stem() const;

返回: !stem().empty()

bool has_extension() const;

返回: !extension().empty()

bool is_absolute() const;

返回:如果 root_path() 的元素唯一地标识一个目录,则返回 true;否则,返回 false

[注意:在 POSIX 系统上,如果有根目录,则路径被认为是绝对的;在 Windows 上,如果既有根名称又有根目录,则路径被认为是绝对的。—结束注意]

bool is_relative() const;

返回: !is_absolute()

path 迭代器 [path.itr]

路径迭代器 iteratorconst_iteratorreverse_iteratorconst_reverse_iterator 遍历存储路径名的元素。

路径迭代器是常量迭代器,满足双向迭代器的要求(C++ Std,24.1.4 双向迭代器 [lib.bidirectional.iterators])。迭代器的 value_type 是 path

[注意:路径迭代器在内部存储其值对象,并且在解除引用时返回对这些内部对象的引用。它们无法与假定通过解除对一个迭代器的引用而获得的引用指向比迭代器本身生存时间更长的对象的迭代器适配器(如 std::reverse_iterator)搭配使用。—结束注意]

调用 path 对象的任何非 const 成员函数都将使所有引用该对象元素的迭代器无效。

前向遍历顺序如下

[注释:在有尾部目录分隔符时,在迭代期间将最后一个元素视为 [v3: 点] [v4: 空路径] 可以对目录路径与一般文件路径进行词法(即语法)区分。在基于 POSIX 和 Windows 的操作系统上,这种区分通常无关紧要,但在其他操作系统上可能是一种要求。—注释结束]

向后遍历顺序与向前遍历顺序相反。

iterator begin() const;

返回:向前遍历顺序的第一个元素的迭代器。如果不存在元素,则返回结束迭代器。

iterator end() const;

返回:结束迭代器。

reverse_iterator rbegin() const;

返回:向后遍历顺序的第一个元素的迭代器。如果不存在元素,则返回结束迭代器。

reverse_iterator rend() const;

返回:结束迭代器。

path 注入区域设置 [path.imbued.locale]

path 操作有时需要在 pathname 和一些其他字符串对象之间进行编码转换,其中一个值类型是 char,另一个是 wchar_t。此类转换应由 path::codecvt() 构面执行。

[示例: ... —示例结束]

static std::locale imbue(const std::locale& loc);

影响:loc 的副本存储为注入的 path 区域设置。

返回:之前的注入 path 区域设置。

备注:注入的 path 区域设置的初始值取决于操作系统。它应该是一个具有 codecvt 构面的区域设置,该构面适用于操作系统的 char 字符串编码。请参阅 ([fs.os.examples]). 

static const codecvt_type& codecvt();

返回:注入 path 区域设置的 codecvt 构面。

path 非成员函数 [path.non-member]

bool lexicographical_compare(path::iterator first1, path::iterator last1,
                             path::iterator first2, path::iterator last2);

返回:如果由半开范围 [first1, last1) 定义的元素的 native() 字符串序列按词法小于由半开范围 [first2, last2) 定义的元素的 native() 字符串序列,则返回 true。否则返回 false

备注:如果两个序列具有相同数量的元素,并且其相应的元素相等,则两个序列都不是按词法小于另一个序列。如果一个序列是另一个序列的前缀,则较短的序列按词法小于较长的序列。否则,序列的词法比较产生的结果与第一个不相同的相应元素对的比较结果相同。

[注释:出于历史原因,提供基于 pathlexicographical_compare 算法。—注释结束]

path lexically_normal(const path& p);

概述:返回经过移除冗余当前目录(dot)、父目录(dot-dot)和 目录分隔符 元素的 p

返回:正常格式的 p

备注:使用operator/=组合返回路径。

[示例:

assert(lexically_normal("foo/./bar/..") == "foo");
assert(lexically_normal("foo/.///bar/../") == "foo/.");

以上所有断言都将成功。 在 Windows 上,返回的路径的目录分隔符将是反斜杠,而不是正斜杠,但这不会影响path相等性。—示例结束]

path lexically_relative(const path& p, const path& base);

概述: p 相对于 base 变为相对路径。将空或相同路径视为特殊情况,而不是错误。不解析符号链接。不会首先对 pbase 进行标准化。

备注:使用 std::mismatch(p.begin(), p.end(), base.begin(), base.end()) 确定 pbase 的第一个不匹配元素。使用 operator== 判断元素是否匹配。

返回

[示例:

assert(lexically_relative("/a/d", "/a/b/c") == "../../d");
assert(lexically_relative("/a/b/c", "/a/d") == "../b/c");
assert(lexically_relative("a/b/c", "a") == "b/c");
assert(lexically_relative("a/b/c", "a/b/c/x/y") == "../..");
assert(lexically_relative("a/b/c", "a/b/c") == ".");
assert(lexically_relative("a/b", "c/d") == "");

以上所有断言都将成功。 在 Windows 上,返回的路径的目录分隔符将是反斜杠,而不是正斜杠,但这不会影响path相等性。—示例结束]

[注意:如果需要符号链接跟随语义,请使用操作函数 relative  —注释结束]

[注意:如果需要标准化来确保元素的一致匹配,请使用调用 lexically_normal() 包装 pbase 或两者。—注释结束]

void swap(path& lhs, path& rhs) noexcept;

影响: lhs.swap(rhs)

std::size_t hash_value(const path& p);

返回:路径 p 的哈希值。如果对于两个路径,p1 == p2,则 hash_value(p1) == hash_value(p2)

这允许将路径与 Boost.Hash 一起使用。

bool operator< (const path& lhs, const path& rhs);

返回: return lhs.compare(rhs.begin) < 0

bool operator<=(const path& lhs, const path& rhs);

返回: !(rhs < lhs)

bool operator> (const path& lhs, const path& rhs);

返回: rhs < lhs

bool operator>=(const path& lhs, const path& rhs);

返回: !(lhs < rhs)

bool operator==(const path& lhs, const path& rhs);

返回: !(lhs < rhs) && !(rhs < lhs)

[注意:路径相等性和路径等价性具有不同的语义。

相等性由 path 非成员 operator== 确定,后者仅考虑两个路径的词法表示。因此,path("foo") == "bar" 绝不会为 true

等同性由非成员函数 equivalent() 判定,该函数判定两个路径 解析 为同一文件系统实体。因此,只当两个路径解析为同一文件时,equivalent("foo", "bar") 才会为 true

希望判定两个路径“相同”的程序员必须决定“相同”是指“相同表示”还是“解析为同一真实文件”,并据此选择恰当的函数。—尾注]

bool operator!=(const path& lhs, const path& rhs);

返回: !(lhs == rhs)

path operator/ (const path& lhs, const path& rhs);

返回: path(lhs) /= rhs

path插入器和提取器 [path.io]

插入器和提取器使用双引号 (") 对字符串定界,以便正确往返带有嵌入空格的路径。和号 (&) 作为一个转义字符,因此路径自身可以包含双引号。

template <class Char, class Traits>
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
                                             const path& p);

影响: 将字符插入 os

[注意: 影响类似于

std::basic_string<Char> str(p.string<std::basic_string<Char>>());
os << boost::io::quoted(str, static_cast<Char>('&'));
—结束注释]

返回: os

template <class Char, class Traits>
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is,
                                             path& p);

影响:is 提取字符

[注意: 影响类似于

std::basic_string<Char> str;
is >> boost::io::quoted(str, static_cast<Char>('&'));
p = str;
—结束注释]

返回: is

filesystem_error [class.filesystem_error]

namespace boost
{
  namespace filesystem
  {
      class filesystem_error : public system_error
      {
      public:
        filesystem_error();
        filesystem_error(const filesystem_error&);
        filesystem_error(const std::string& what_arg,
          system::error_code ec);
        filesystem_error(const std::string& what_arg,
          const path& p1, system::error_code ec);
        filesystem_error(const std::string& what_arg,
          const path& p1, const path& p2, system::error_code ec);

        filesystem_error& filesystem_error(const filesystem_error&);
       ~filesystem_error();

        filesystem_error& operator=(const filesystem_error&);

        const path& path1() const;
        const path& path2() const;

        const char * what() const;
      };
  }  // namespace filesystem
}  // namespace boost

类模板 filesystem_error 定义了作为异常抛出的对象类型,用于报告该参考文档中所述函数产生的文件系统错误。

filesystem_error 成员 [filesystem_error.members]

filesystem_error(const std::string& what_arg, error_code ec);

后置条件

表达式
runtime_error::what() what_arg.c_str()
code() ec
path1().empty() true
path2().empty() true
filesystem_error(const std::string& what_arg, const path& p1, error_code ec);

后置条件

表达式
runtime_error::what() what_arg.c_str()
code() ec
path1() 对存储的 p1 副本的引用
path2().empty() true
filesystem_error(const std::string& what_arg, const path& p1, const path& p2, error_code ec);

后置条件

表达式
runtime_error::what() what_arg.c_str()
code() ec
path1() 对存储的 p1 副本的引用
path2() 对存储的 p2 副本的引用
const path& path1() const;

返回: 对由构造器存储的 p1 副本的引用,或者,如果不存在,则返回一个空路径。

const path& path2() const;

返回: 对由构造器存储的 p2 副本的引用,或者,如果不存在,则返回一个空路径。

const char* what() const;

返回:包含 runtime_error::what() 的字符串。具体格式未指定。鼓励但不强制实现包括 path1.native_string()(如果非空)、path2.native_string()(如果非空)和 system_error::what() 字符串在返回字符串中。

枚举 file_type [enum.file_type]

此枚举指定用于识别文件类型的常量。

常量名称 含义
status_error 尝试获取文件状态时出错。简单地找不到文件并非被视为状态错误。
file_not_found 找不到文件
regular_file 普通文件
directory_file 目录文件
symlink_file 符号链接文件
block_file 块特殊文件
character_file 字符特殊文件
fifo_file FIFO 或管道文件
socket_file 套接字文件
type_unknown 文件存在,但属于上述任何情况中未涵盖的特定于系统的类型。

枚举 perms [enum.perms]

enum 指定用于识别文件权限的位掩码常量。ISO/IEC 9945 (POSIX) 指定实际值,并且此处已采用这些值,因为它们对许多 POSIX 用户非常熟悉并根深蒂固。

Windows:目前会忽略除了写之外的所有权限。只有一个写权限;为所有者、组或其他人设置写权限会设置所有人的写权限,而移除所有者、组或其他人的写权限会移除所有人的写权限。

名称
(八进制)
ISO/IEC 9945
定义或注释

no_perms

0 未为文件设置任何权限。注意:file_not_foundno_perms 而不是 perms_not_known
owner_read0400 S_IRUSR 所有者的读取权限
owner_write0200 S_IWUSR 所有者的写入权限
owner_exe0100 S_IXUSR 所有者的执行/搜索权限
owner_all0700 S_IRWXU 所有者的读取、写入、执行/搜索权限;owner_read | owner_write | owner_exe
group_read040 S_IRGRP 组的读取权限
group_write020 S_IWGRP 组的写入权限
group_exe010 S_IXGRP 组的执行/搜索权限
group_all070 S_IRWXG 组的读取、写入、执行/搜索权限;group_read | group_write | group_exe
others_read04 S_IROTH 其他人的读取权限
others_write02 S_IWOTH 其他人的写入权限
others_exe01 S_IXOTH 其他人的执行/搜索权限
others_all07 S_IRWXO 其他人的读取、写入、执行/搜索权限;others_read | others_write | others_exe
all_all0777 owner_all | group_all | others_all
set_uid_on_exe04000 S_ISUID 在执行时设置用户 ID
set_gid_on_exe02000 S_ISGID 执行时设置组 ID
sticky_bit 01000 S_ISVTX 取决于操作系统。本身不可移植,甚至在 ISO/IEC 9945 操作系统之间。
perms_mask07777   all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit
perms_not_known0xFFFF权限未知,例如在没有指定权限的情况下创建 file_status 对象时

add_perms

0x1000

permissions() 将自变量权限位添加到文件的当前位

remove_perms0x2000 permissions() 从文件的当前位中移除自变量权限位
symlink_perms0x4000 在 ISO/IEC 9945 permissions() 解析符号链接,除非指定了 symlink_perms。在 Windows 中, permissions() 永远不会解析符号链接,因此毫无意义。由于 permissions() 始终解析符号链接,因此在 Mac OS X 和一些其他 BSD 系统中毫无意义。不要纠结。

类 file_status [class.file_status]

namespace boost
{
  namespace filesystem
  {
      class file_status
      {
      public:

        // constructors
        file_status() noexcept;
        explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;

        // compiler generated
        file_status(const file_status&) noexcept;
        file_status& operator=(const file_status&) noexcept;
       ~file_status() noexcept;

        // observers
        file_type  type() const noexcept;
        perms      permissions() const noexcept;

        // modifiers
        void       type(file_type ft) noexcept;
        void       permissions(perms prms) noexcept;
      };
  }  // namespace filesystem
}  // namespace boost

file_status 类型的对象存储有关文件类型和权限的信息。

file_status 构造函数 [file_status.cons]

explicit file_status() noexcept;

后置条件: type() == status_errorpermissions() == perms_not_known

explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;

后置条件: type() == ftpermissions() == prms

file_status 观察程序 [file_status.obs]

file_type type() const noexcept;

返回: 最最近一次调用构造函数、operator= 或者 type(file_type) 函数的 后置条件 中所指定的 type() 的值。

perms permissions() const noexcept;

返回: 最最近一次调用构造函数、operator= 或者 permissions(perms) 函数的 后置条件 中所指定的 permissions() 的值。

file_status 修改程序 [file_status.mods]

void type(file_type ft) noexcept;

后置条件: type() == ft

void permissions(perms prms) noexcept;

后置条件: permissions() == prms

directory_entry [class.directory_entry]

namespace boost
{
  namespace filesystem
  {
      class directory_entry
      {
      public:

        // constructors and destructor
        directory_entry();
        directory_entry(const directory_entry&);
        explicit directory_entry(const path& p);
        directory_entry(const path& p, system::error_code& ec);       // v4-only
        directory_entry(const path& p, file_status st,                // v3-only
          file_status symlink_st=file_status());
       ~directory_entry();

        // modifiers
        directory_entry& operator=(const directory_entry&);
        void assign(const path& p);
        void assign(const path& p, system::error_code& ec);           // v4-only
        void assign(const path& p, file_status st,                    // v3-only
          file_status symlink_st=file_status());
        void replace_filename(const path& p);
        void replace_filename(const path& p, system::error_code& ec); // v4-only
        void replace_filename(const path& p, file_status st,          // v3-only
          file_status symlink_st=file_status());

        void refresh();
        void refresh(system::error_code& ec);

        // observers
        const path&  path() const;

        file_status  status() const;
        file_status  status(system::error_code& ec) const;
        file_status  symlink_status() const;
        file_status  symlink_status(system::error_code& ec) const;
        file_type file_type() const;
        file_type file_type(system::error_code& ec) const;
        file_type symlink_file_type() const;
        file_type symlink_file_type(system::error_code& ec) const;

        bool exists() const;
        bool exists(system::error_code& ec) const;
        bool is_regular_file() const;
        bool is_regular_file(system::error_code& ec) const;
        bool is_directory() const;
        bool is_directory(system::error_code& ec) const;
        bool is_symlink() const;
        bool is_symlink(system::error_code& ec) const;
        bool is_block_file() const;
        bool is_block_file(system::error_code& ec) const;
        bool is_character_file() const;
        bool is_character_file(system::error_code& ec) const;
        bool is_fifo() const;
        bool is_fifo(system::error_code& ec) const;
        bool is_socket() const;
        bool is_socket(system::error_code& ec) const;
        bool is_reparse_file() const;
        bool is_reparse_file(system::error_code& ec) const;
        bool is_other() const;
        bool is_other(system::error_code& ec) const;

        bool operator< (const directory_entry& rhs);
        bool operator==(const directory_entry& rhs);
        bool operator!=(const directory_entry& rhs);
        bool operator< (const directory_entry& rhs);
        bool operator<=(const directory_entry& rhs);
        bool operator> (const directory_entry& rhs);
        bool operator>=(const directory_entry& rhs);
      private:
        path                 m_path;           // for exposition only
        mutable file_status  m_status;         // for exposition only; stat()-like
        mutable file_status  m_symlink_status; // for exposition only; lstat()-like
      };

  }  // namespace filesystem
}  // namespace boost

directory_entry 对象存储一个 path 对象,以及关于路径标识的文件的某些缓存信息。目前,缓存信息包括非符号链接状态的 file_status 对象以及符号链接状态的 file_status 对象。

[注意: 由于对路径名执行 status() 可能是一种相对昂贵的操作,因此一些操作系统提供状态信息作为目录遍历的副产品。缓存此类状态信息可以显著节省时间。在文件系统竞态的情况下,缓存结果和非缓存结果可能有所不同。——结束注意]

对含 15,047 个条目的目录进行迭代的实际冷启动计时,针对未缓存状态查询为六秒,而针对缓存状态查询为一秒。Windows XP,3.0 GHz 处理器,带有中等速度的硬盘驱动器。对于将状态作为目录迭代的副产品提供的 Linux 和 BSD 派生系统,可预期类似的加速。

[注意:缓存信息的确切集合可能因一个 Boost.Filesystem 版本与另一个版本不同,以及因不同的操作系统和基础文件系统不同而异。用户代码不得依赖于某条信息是否被缓存。这意味着调用 directory_entry 的大部分观察者和修改器可能会或可能不会导致可能失败的文件系统查询。信息缓存是专门旨在减少此类查询数量的性能特性。— 结束注释]

directory_entry 构造器 [directory_entry.cons]

directory_entry();

后置条件

表达式
path().empty() true
status() file_status()
symlink_status() file_status()
explicit directory_entry(const path& p);
directory_entry(const path& p, system::error_code& ec); // v4-only

效果

v3: 根据 p 初始化 m_path,并对 m_statusm_symlink_status 执行默认构造。

[注意:将在调用者查询时或通过显式调用 refresh 时更新缓存的文件状态。— 结束注释]

v4: 根据 p 初始化 m_path,并分别调用 refresh()refresh(ec)

后置条件:如果未出现错误则 path() == p,否则 path().empty() == true

directory_entry(const path& p, file_status st, file_status symlink_st=file_status()); // v3-only

v3: 后置条件:

表达式
path() p
status() st
symlink_status() symlink_st

directory_entry 修改器 [directory_entry.mods]

void assign(const path& p);
void assign(const path& p, system::error_code& ec); // v4-only

效果

v3:p 赋值给 m_path,将 file_status() 赋值给 m_statusm_symlink_status

[注意:将在调用者查询时或通过显式调用 refresh 时更新缓存的文件状态。— 结束注释]

v4:p 赋值给 m_path,并分别调用 refresh()refresh(ec)。如果出现错误,则缓存数据的数值未指定。

void assign(const path& p, file_status st, file_status symlink_st=file_status()); // v3-only

v3: 后置条件:

表达式
path() p
status() st
symlink_status() symlink_st
void replace_filename(const path& p);
void replace_filename(const path& p, system::error_code& ec); // v4-only

效果

v3: 调用 m_path.replace_filename(p),并将 file_status() 赋值给 m_statusm_symlink_status

[注意:将在调用者查询时或通过显式调用 refresh 时更新缓存的文件状态。— 结束注释]

v4: 调用 m_path.replace_filename(p),然后分别调用 refresh()refresh(ec)。如果出现错误,则缓存数据的数值未指定。

void replace_filename(const path& p, file_status st, file_status symlink_st=file_status()); // v3-only

作用: v3: 调用 m_path.replace_filename(p),并将 st 赋值给 m_status,将 symlink_st 赋值给 m_symlink_status

void refresh();
void refresh(system::error_code& ec);

作用:通过关于由 m_path 标识的文件的文件系统查询更新所有缓存数据。如果出现错误,则缓存数据的数值未指定。

directory_entry 观察者 [directory_entry.obs]

const path& path() const;

返回: m_path

file_status status() const;
file_status status(system::error_code& ec) const;

作用:如果 !status_known(m_status),则分别调用 refresh()refresh(ec)

返回: m_status

抛出:错误报告 中所指定。

file_status  symlink_status() const;
file_status  symlink_status(system::error_code& ec) const;

作用:如果 !status_known(m_symlink_status),则分别调用 refresh()refresh(ec)

返回: m_symlink_status

抛出:错误报告 中所指定。

file_type file_type() const;
file_type file_type(system::error_code& ec) const;

效果: 分别相当于 status().type()status(ec).type()

[注意:如果文件类型的信息为缓存信息而权限信息不是缓存信息时,此实现可能比调用 status 更有效率。—end note]

file_type symlink_file_type() const;
file_type symlink_file_type(system::error_code& ec) const;

效果: 分别相当于 symlink_status().type()symlink_status(ec).type()

[注意:如果文件类型的信息为缓存信息而权限信息不是缓存信息时,此实现可能比调用 symlink_status 更有效率。—end note]

bool exists() const;
bool exists(system::error_code& ec) const;

效果: 分别相当于 exists(status())exists(status(ec))

bool is_regular_file() const;
bool is_regular_file(system::error_code& ec) const;

效果: 分别相当于 is_regular_file(status())is_regular_file(status(ec))

bool is_directory() const;
bool is_directory(system::error_code& ec) const;

效果: 分别相当于 is_directory(status())is_directory(status(ec))

bool is_symlink() const;
bool is_symlink(system::error_code& ec) const;

效果: 分别相当于 is_symlink(symlink_status())is_symlink(symlink_status(ec))

bool is_block_file() const;
bool is_block_file(system::error_code& ec) const;

效果: 分别相当于 is_block_file(status())is_block_file(status(ec))

bool is_character_file() const;
bool is_character_file(system::error_code& ec) const;

效果: 分别相当于 is_character_file(status())is_character_file(status(ec))

bool is_fifo() const;
bool is_fifo(system::error_code& ec) const;

效果: 分别相当于 is_fifo(status())is_fifo(status(ec))

bool is_socket() const;
bool is_socket(system::error_code& ec) const;

效果: 分别相当于 is_socket(status())is_socket(status(ec))

bool is_reparse_file() const;
bool is_reparse_file(system::error_code& ec) const;

效果: 分别相当于 is_reparse_file(symlink_status())is_reparse_file(symlink_status(ec))

bool is_other() const;
bool is_other(system::error_code& ec) const;

效果: 分别相当于 is_other(status())is_other(status(ec))

bool operator==(const directory_entry& rhs);

返回值: m_path == rhs.m_path

bool operator!=(const directory_entry& rhs);

返回值: m_path != rhs.m_path

bool operator< (const directory_entry& rhs);

返回值: m_path < rhs.m_path

bool operator<=(const directory_entry& rhs);

返回值: m_path <= rhs.m_path

bool operator> (const directory_entry& rhs);

返回值: m_path > rhs.m_path

bool operator>=(const directory_entry& rhs);

返回值: m_path >= rhs.m_path

directory_iterator [类.directory_iterator]

directory_iterator 类型对象提供了标准库兼容,可重复迭代目录内容的功能。同样请参见 recursive_directory_iterator 类。

namespace boost
{
  namespace filesystem
  {
      class directory_iterator
      {
      public:
        // member functions

        directory_iterator() noexcept;  // creates the "end" iterator
        directory_iterator(const directory_iterator&);
        explicit directory_iterator(const path& p, directory_options opts = directory_options::none);
        directory_iterator(const path& p, system::error_code& ec);
        directory_iterator(const path& p, directory_options opts, system::error_code& ec);
       ~directory_iterator();

        directory_iterator& operator=(const directory_iterator&);

        directory_iterator& operator++();
        directory_iterator& increment(system::error_code& ec);

        // other members as required by
        //  C++ Std, 24.1.1 Input iterators [input.iterators]
      };

  }  // namespace filesystem
}  // namespace boost

directory_iterator 满足输入迭代器的要求(C++ 标准,24.2.1 输入迭代器 [input.iterators])。

directory_iterator 从构造其的目录中读取连续元素,就像调用 ISO/IEC 9945 readdir() 或 readdir_r()一样。构造 directory_iterator 后,以及每次调用 operator++ 时,它都会读取一个目录并将其信息存储在 directory_entry 类型的对象中。operator++ 不是平等保持的,即,i == j 并不意味着 ++i == ++j

[注意: 这种不保持平等带来的实际结果是,只能对目录迭代器使用单次执行算法。—end note]

如果已到达目录元素的末尾,则该迭代器应变为最终迭代器值。不带参数的构造函数 directory_iterator() 始终构造一个最终迭代器对象,该对象应是最终条件下的唯一有效迭代器。最终迭代器中 operator* 的结果未定义。对于任何其他迭代器值,将返回 const directory_entry&。最终迭代器中 operator-> 的结果是未定义行为。对于任何其他迭代器值,将返回 const directory_entry*

两个最终迭代器始终相等。最终迭代器不应等于非最终迭代器。

上述措辞基于标准库的 istream_iterator 措辞。

通过对 directory_iterator 进行解引用而获取的 directory_entry 对象的 path() 成员调用结果是对 path 对象的引用,该对象由使用作为附加目录条目文件名的迭代器构造目录参数组成,就像使用 operator/= 一样。

目录迭代不应为当前 () 和父 (双点) 目录产生目录条目。

通过对 directory_iterator 的连续增量进行解引用而获取的目录条目的顺序未指定。

[注意:执行目录迭代的程序可能希望测试通过对目录迭代器解引用获取的路径是否实际存在。该路径可能是指向不存在文件的符号链接。出于移除和重命名条目的目的而递归遍历目录树的程序可能希望避免跟随符号链接。

如果在为目录构造 directory_iterator 之后从目录中移除或添加了文件,则后续递增迭代器是否最终会导致迭代器的值是移除或添加的目录条目无法确定。参见 ISO/IEC 9945 readdir_r()——结束注意]

directory_iterator 成员 [directory_iterator.members]

directory_iterator() noexcept;

效果:构造最终迭代器。

explicit directory_iterator(const path& p, directory_options opts = directory_options::none);
directory_iterator(const path& p, system::error_code& ec);
directory_iterator(const path& p, directory_options opts, system::error_code& ec);

效果:如果任何目录解析为 p,则构造代表其中第一个条目的迭代器;否则,构造最终迭代器。如果使用 permission_denied 错误并 (opts & directory_options::skip_permission_denied) != 0 打开目录失败,则构造最终迭代器并忽略错误(操作顺利完成)。如果未指定 opts,则假定其为 directory_options::none

抛出:错误报告 中所指定。

[注意:若要迭代当前目录,请使用 directory_iterator(".") 而不是 directory_iterator("")——结束注意]

directory_iterator& operator++();
directory_iterator& increment(system::error_code& ec);

效果:如 C++ 标准 24.1.1 中所规范的输入迭代器 [input.iterators]。如果出错,则迭代器将保留在最终状态。

返回值: *this

抛出:错误报告 中所指定。

directory_iterator 非成员函数

const directory_iterator& begin(const directory_iterator& iter);

返回: iter

directory_iterator end(const directory_iterator&);

返回: directory_iterator()

recursive_directory_iterator [class.rec.dir.itr]

类型为 recursive_directory_iterator 的对象提供对某个目录中内容的符合标准库要求的迭代,包括递归进入它的子目录中。

namespace boost
{
  namespace filesystem
  {
      class recursive_directory_iterator :
        public iterator<input_iterator_tag, directory_entry>
      {
      public:

        // constructors and destructor
        recursive_directory_iterator() noexcept;
        recursive_directory_iterator(const recursive_directory_iterator&);
        explicit recursive_directory_iterator(const path& p,
          directory_options opts = directory_options::none);
        recursive_directory_iterator(const path& p,
          directory_options opts, system::error_code& ec);
        recursive_directory_iterator(const path& p, system::error_code& ec);
       ~recursive_directory_iterator();

        // observers
        int depth() const noexcept;
        bool recursion_pending() const noexcept;

        // modifiers
        recursive_directory_iterator& operator=(const recursive_directory_iterator&);

        recursive_directory_iterator& operator++();
        recursive_directory_iterator& increment(system::error_code& ec);

        void pop();
        void pop(system::error_code& ec);
        void disable_recursion_pending(bool value = true) noexcept;

        // other members as required by
        //  C++ Std, Input iterators [input.iterators]

      private:
        // actual data members will probably be stored in a shared object,
        // or some similar mechanism, to achieve the required input iterator
        // copy semantics
        int            m_depth;              // for exposition only
        bool           m_recursion_pending;  // for exposition only
        directory_options m_options;         // for exposition only
      };

  }  // namespace filesystem
}  // namespace boost

除非另有说明,否则 recursive_directory_iterator 的行为与 directory_iterator 相同。

recursive_directory_iterator() noexcept;

效果:构造最终迭代器。

explicit recursive_directory_iterator(const path& p, directory_options opts = directory_options::none);
recursive_directory_iterator(const path& p, directory_options opts, system::error_code& ec);
recursive_directory_iterator(const path& p, system::error_code& ec);

效果:构造一个表示目录 p (如果存在)中的第一个条目的迭代器;否则,构造一个尾部迭代器。

后置条件: 除非构造一个尾部迭代器,否则 depth() == 0 && recursion_pending() == true && m_options == opts。对于没有 opts 参数的签名,假定 optsdirectory_options::none

抛出:错误报告 中所指定。

[注意:要对当前目录进行迭代,使用 recursive_directory_iterator(".") 而不是 recursive_directory_iterator("")—end 注释]

[注意:默认情况下,recursive_directory_iterator 不会遵循目录符号链接。要遵循目录符号链接,请在 opts 中指定 directory_options::follow_directory_symlink—end 注释]

int depth() const noexcept;

要求: *this != recursive_directory_iterator()

返回: m_depth

bool recursion_pending() const noexcept;

要求: *this != recursive_directory_iterator()

返回: m_recursion_pending

recursive_directory_iterator& operator++();
recursive_directory_iterator& increment(system::error_code& ec);

效果:如 C++ 标准 24.1.1 所指定的,输入迭代器 [input.iterators],除非

如果操作完成时出现错误,那么

后置条件: recursion_pending() == true

返回值: *this

抛出:错误报告 中所指定。

void pop();
void pop(system::error_code& ec);

要求: *this != recursive_directory_iterator()

效果:如果 depth() == 0,将 *this 设置为 recursive_directory_iterator()。否则,--m_depth 将停止迭代当前正在迭代的目录,并继续迭代父目录。

如果操作完成时出现错误,那么

void disable_recursion_pending(bool value = true) noexcept;

要求: *this != recursive_directory_iterator()

后置条件:recursion_pending() == !value

[注意:这些函数用于防止目录中的意外递归。 — 注释结束]

recursive_directory_iterator 非成员函数

const recursive_directory_iterator& begin(const recursive_directory_iterator& iter);

返回: iter

recursive_directory_iterator end(const recursive_directory_iterator&);

返回: recursive_directory_iterator()

操作函数[fs.op.funcs]

操作函数查询或修改外部存储中的文件,包括目录。

操作函数通过将 path 类的对象解析为文件层次结构中的特定文件来访问文件。路径解析方式与 ISO/IEC 9945 中的路径名解析机制一样。

[注意:由于硬件故障、网络故障、文件系统竞争和许多其他类型的错误经常在文件系统操作中发生,因此用户应该知道任何文件系统操作函数,无论看起来多么无害,都可能会遇到错误。 请见错误报告— 注释结束]

path absolute(const path& p, const path& base=current_path());
path absolute(const path& p, system::error_code& ec);
path absolute(const path& p, const path& base, system::error_code& ec);

返回:如果 p.is_absolute()true,则返回 p,否则返回根据下表组成的绝对路径

  p.
has_root_directory()
!p.has_root_directory()
p.has_root_name() 返回p 返回
 p.root_name()
 / absolute(base)
    .root_directory()
 / absolute(base)
    .relative_path()
 / p.relative_path()
!p.has_root_name() 返回
 absolute(base)
  .root_name()
 / p
返回 absolute(base)
 / p

对于没有base参数的重载,basecurrent_path()

[注意:对于返回的路径,rp, 即 rp.is_absolute()true— 注释结束]

抛出:错误报告 中所指定。

path canonical(const path& p, const path& base = current_path());
path canonical(const path& p, system::error_code& ec);
path canonical(const path& p, const path& base, system::error_code& ec);

概述:p 转换为绝对路径,该路径没有符号链接、点-点 元素。测试符号链接的路径元素的方法与调用 is_symlink 一样,并且需要 absolute(p, base) 存在。

返回:一个规范路径,该路径引用与 absolute(p, base) 相同的文件系统对象。对于没有 base 参数的重载,basecurrent_path()

抛出: 如错误报告中所述。

备注: !exists(absolute(p, base))是一个错误。

[注意:规范路径名允许对路径进行安全检查(例如,此路径位于 /home/goodguy 还是 /home/badguy 中?) — 注释结束]

void copy(const path& from, const path& to);
void copy(const path& from, const path& to, system::error_code& ec);

效果: copy(from, to, copy_options::none[, ec])

抛出:错误报告 中所指定。

void copy(const path& from, const path& to, copy_options options);
void copy(const path& from, const path& to, copy_options options, system::error_code& ec);

前置条件:options 最多包含以下各组中的一个选项

效果:ft 为通过以下方式获取的 file_status 对象

然后,如果出现以下情况,则报告错误否则,如果 is_symlink(f),则否则,如果 is_regular_file(f),则否则,如果 is_directory(f),则否则,对于 f 的所有不受支持文件类型报错。

抛出:错误报告 中所指定。

bool copy_file(const path& from, const path& to);
bool copy_file(const path& from, const path& to, system::error_code& ec);

作用:return copy_file(from, to, copy_options::none[, ec])

抛出:错误报告 中所指定。

bool copy_file(const path& from, const path& to, copy_options options);
bool copy_file(const path& from, const path& to, copy_options options, system::error_code& ec);

前置条件:options 最多包含以下各组中的一个选项

作用:在以下情况下报错

否则,在以下情况下成功返回,且无作用否则

返回:如果在不报错的情况下成功复制文件,则返回 true,否则返回 false

抛出:错误报告 中所指定。

[注意:当指定了 copy_options::update_existing 时,检查 fromto 的写入时间不一定和复制操作同时进行。在检查了文件修改时间后但在复制开始之前,另一个进程可能会创建或修改由 to 标识的文件。在这种情况下,目标文件会被覆盖。]

[注意:copy_options::synchronize_datacopy_options::synchronize 选项可能会对性能造成重大影响。copy_options::synchronize_data 选项可能比 copy_options::synchronize 的开销更小。但是,如果没有这些选项,在 copy_file 返回后,不保证复制的文件在系统故障时能够得到完整写入和保存。在函数返回后,任何延迟的写入操作都可能失败,在将数据实际写入底层媒介时发生此情况时,此错误将不会报告给调用者。]

[注意:copy_options::ignore_attribute_errors 选项可以在调用者不要求复制文件属性时使用。实现允许尝试复制文件属性,但如果复制失败,仍然会成功进行文件复制操作。此选项在并不完全支持文件属性操作的文件系统中可能有用。]

void copy_symlink(const path& existing_symlink, const path& new_symlink);
void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec);

效果: create_symlink(read_symlink(existing_symlink[, ec]), new_symlink[, ec])

抛出:错误报告 中所指定。

bool create_directories(const path& p);
bool create_directories(const path& p, system::error_code& ec);

效果:通过调用 create_directory()来为不存在的p的任何元素建立后置条件。

后置条件: is_directory(p)

返回:如果创建了新目录,则返回true,否则返回 false

抛出:错误报告 中所指定。

复杂性: O(n+1),其中n是不存在的p元素的数量。

bool create_directory(const path& p);
bool create_directory(const path& p, system::error_code& ec);
bool create_directory(const path& p, const path& existing);
bool create_directory(const path& p, const path& existing, system::error_code& ec);

效果:通过尝试创建p解析到的目录(如同通过ISO/IEC 9945 mkdir()),建立后置条件。对于没有existing参数的重载,使用S_IRWXU|S_IRWXG|S_IRWXO模式创建新目录。带existing参数的重载从 existing(必须是现有目录的路径)获取模式。在 Windows 中,如果未指定existing,则使用CreateDirectoryW(p.c_str(), NULL),否则使用CreateDirectoryExW(existing.c_str(), p.c_str(), NULL)。由于p解析为现有目录而导致的创建失败不应被视为错误。

后置条件: is_directory(p)

返回:如果创建了新目录,则返回true,否则返回false

抛出:错误报告 中所指定。

void create_directory_symlink(const path& to, const path& new_symlink);
void create_directory_symlink(const path& to, const path& new_symlink, system::error_code& ec);

效果:如同通过ISO/IEC 9945 symlink(),来建立后置条件。

后置条件: new_symlink解析为一个符号链接文件,其中包含to的未指定表示。

抛出:错误报告 中所指定。

[注意:某些操作系统(例如 Windows)要求符号链接创建标识该链接为一个目录。便携式代码应使用create_directory_symlink()创建目录符号链接,而不是使用create_symlink() —end note]

[注意:某些操作系统根本不支持符号链接,或只支持正规文件的符号链接。某些文件系统不支持符号链接,而不考虑操作系统 - 例如存储卡和闪存驱动器上使用的 FAT 文件系统。 —end note]

void create_hard_link(const path& to, const path& new_hard_link);
void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec);

效果:如同通过ISO/IEC 9945 link(),来建立后置条件。

后置条件

抛出:错误报告 中所指定。

[注意:某些操作系统根本不支持硬链接,或只支持正规文件的硬链接。某些文件系统不支持硬链接,而不考虑操作系统 - 例如存储卡和闪存驱动器上使用的 FAT 文件系统。某些文件系统限制每个文件链接的数量。 —end note]

void create_symlink(const path& to, const path& new_symlink);
void create_symlink(const path& to, const path& new_symlink, system::error_code& ec);

效果:如同通过ISO/IEC 9945 symlink(),来建立后置条件。

后置条件: new_symlink解析为一个符号链接文件,其中包含to的未指定表示。

抛出:错误报告 中所指定。

[注意:某些操作系统根本不支持符号链接,或只支持正规文件的符号链接。某些文件系统不支持符号链接,而不考虑操作系统 - 例如存储卡和闪存驱动器上使用的 FAT 文件系统。 —end note]

path current_path();
path current_path(system::error_code& ec);

返回:当前工作目录路径,如同通过ISO/IEC 9945 getcwd()is_absolute()对于返回的路径为 true。

抛出:错误报告 中所指定。

[注:选择 current_path() 名称是为了强调返回的是路径,而不仅仅是一个目录名称。

很多操作系统返回的当前路径是一个危险的全局变量。它可能会由第三方或系统库函数意外更改,或由其他线程意外更改。  —脚注]

void current_path(const path& p);
void current_path(const path& p, system::error_code& ec);

影响:建立后条件,类似于 ISO/IEC 9945 chdir()

后条件: equivalent(p, current_path())

抛出:错误报告 中所指定。

[注:很多操作系统的当前路径都是一个危险的全局状态。它可能会由第三方或系统库函数意外更改,或由其他线程意外更改。  —脚注]

bool exists(file_status s) noexcept;

返回值: status_known(s) && s.type() != file_not_found

bool exists(const path& p);
bool exists(const path& p, system::error_code& ec) noexcept;

返回值: exists(status(p))exists(status(p, ec))

抛出:错误报告 中所指定。

bool equivalent(const path& p1, const path& p2);
bool equivalent(const path& p1, const path& p2, system::error_code& ec);

返回值:如果 p1p2 解析为同一文件系统实体,则返回 true,否则返回 false

如果两个候选实体位于相同位置的同一设备上,则两个路径会被视为解析为同一文件系统实体。这由 ISO/IEC 9945 stat 结构(类似于通过 stat() 获得的两个路径的 st_devst_ino 值相等)的值确定。

[注:ISO/IEC 9945 要求“st_dev 在本地区域网络中必须是唯一的”。保守的 ISO/IEC 9945 实现还可能会检查相等的 st_sizest_mtime 值。Windows 实现可能会使用 GetFileInformationByHandle() 作为 stat() 的替代品,并在 dwVolumeSerialNumbernFileIndexHighnFileIndexLownFileSizeHighnFileSizeLowftLastWriteTime.dwLowDateTimeftLastWriteTime.dwHighDateTime 具有相等值的情况下认为是“相同”。—脚注]

抛出:错误报告 中所述。[v3: !exists(p1) && !exists(p2) 是一个错误。如果仅一个路径不存在,则在没有错误的情况下返回 false。] [v4: !exists(p1) || !exists(p2) 是一个错误。]

uintmax_t file_size(const path& p);
uintmax_t file_size(const path& p, system::error_code& ec);

返回值:如果 exists(p) && is_regular_file(p),则文件 p 解析到的字节大小(由 ISO/IEC 9945 stat 结构成员 st_size 的值确定,类似于通过 ISO/IEC 9945 stat() 获得)。否则,返回 static_cast<uintmax_t>(-1)

抛出:错误报告 中所指定。

uintmax_t hard_link_count(const path& p);
uintmax_t hard_link_count(const path& p, system::error_code& ec);

返回值: p 的硬链接数。

抛出:错误报告 中所指定。

const path& initial_path();
const path& initial_path(system::error_code& ec);

返回值:首次调用 initial_path() 时的 current_path()

[注: initial_path() 不是线程安全的,如果在当前目录更改后调用,它可能返回一个不良结果。可以通过在进入 main() 时立即调用 initial_path() 来避免这些问题。  —脚注]

抛出:对于首次调用,如 错误报告 中所述。后续调用不抛出任何内容。

bool is_block_file(file_status s) noexcept;

返回: s.type() == block_file

bool is_block_file(const path& p);
bool is_block_file(const path& p, system::error_code& ec) noexcept;

返回: is_block_file(status(p))is_block_file(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_character_file(file_status s) noexcept;

返回: s.type() == character_file

bool is_character_file(const path& p);
bool is_character_file(const path& p, system::error_code& ec) noexcept;

返回: is_character_file(status(p))is_character_file(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_directory(file_status s) noexcept;

返回: s.type() == directory_file

bool is_directory(const path& p);
bool is_directory(const path& p, system::error_code& ec) noexcept;

返回: is_directory(status(p))is_directory(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_empty(const path& p);
bool is_empty(const path& p, system::error_code& ec);

影响: 确定 file_status s,如同 status(p, ec)

返回: is_directory(s)
         ? directory_iterator(p) == directory_iterator()
         : file_size(p) == 0;

bool is_fifo(file_status s) noexcept;

返回: s.type() == fifo_file

bool is_fifo(const path& p);
bool is_fifo(const path& p, system::error_code& ec) noexcept;

返回: is_fifo(status(p))is_fifo(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_other(file_status s) noexcept;

返回: return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s)

bool is_other(const path& p);
bool is_other(const path& p, system::error_code& ec) noexcept;

返回: is_other(status(p))is_other(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_regular_file(file_status s) noexcept;

返回: s.type() == regular_file

bool is_regular_file(const path& p);
bool is_regular_file(const path& p, system::error_code& ec) noexcept;

返回: is_regular_file(status(p))is_regular_file(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_reparse_file(file_status s) noexcept;

返回: s.type() == reparse_file

bool is_reparse_file(const path& p);
bool is_reparse_file(const path& p, system::error_code& ec) noexcept;

返回: is_reparse_file(symlink_status(p))is_reparse_file(symlink_status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_socket(file_status s) noexcept;

返回: s.type() == socket_file

bool is_socket(const path& p);
bool is_socket(const path& p, system::error_code& ec) noexcept;

返回: is_socket(status(p))is_socket(status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

bool is_symlink(file_status s) noexcept;

返回: s.type() == symlink_file

bool is_symlink(const path& p);
bool is_symlink(const path& p, system::error_code& ec) noexcept;

返回: is_symlink(symlink_status(p))is_symlink(symlink_status(p, ec))。带 ec 参数的重载在出现错误时返回 false

抛出: filesystem_error;带 ec 参数的重载不抛出任何内容。

std::time_t creation_time(const path& p);
std::time_t creation_time(const path& p, system::error_code& ec);

返回: p 解析到的文件的创建时间。

抛出:错误报告 中所指定。

[注意: 并非所有平台都支持查询文件创建时间。在不支持的情况下,此操作将因 errc::function_not_supported 错误代码而失败。—结束注释]

std::time_t last_write_time(const path& p);
std::time_t last_write_time(const path& p, system::error_code& ec);

返回: p 的上次数据修改时间,根据 ISO/IEC 9945 的 stat 结构成员 st_mtime 的值而确定,此值通过 ISO/IEC 9945 stat() 确定。

抛出:错误报告 中所指定。

void last_write_time(const path& p, const std::time_t new_time);
void last_write_time(const path& p, const std::time_t new_time, system::error_code& ec);

影响:p 解析到的文件的上次数据修改时间设置为 new_time,如同 ISO/IEC 9945 stat() 后跟 ISO/IEC 9945 utime()

抛出:错误报告 中所指定。

[注意:未指定last_write_time(p) == new_time 的后置条件,因为它对时间粒度粗略的文件系统可能不成立。—注释结束]

void permissions(const path& p, perms prms);
void permissions(const path& p, perms prms, system::error_code& ec);

需要:!((prms & add_perms) && (prms & remove_perms)).

影响:将自 prms 中有效权限位应用到 文件 p解析为的文件中,就像由 ISO/IEC 9945 fchmodat()一样。有效权限位由下表中指定内容决定。

prms中存在的位 应用的有效位
add_permsremove_perms均不存在 prms & perms_mask
add_perms

status(p).permissions() | (prms & perms_mask)

remove_perms status(p).permissions() & ~(prms & perms_mask)

[注意:从概念而言,权限被视为位,但实际实现可能会使用其他机制。—注释结束]

抛出:错误报告 中所指定。

path read_symlink(const path& p);
path read_symlink(const path& p, system::error_code& ec);

返回:如果 p解析为符号链接,则返回包含该符号链接内容的 path 对象。否则返回一个空 path 对象。

引发:错误报告 中所说明的。[注意:如果 p 没有解析为符号链接,则是一个错误。—注释结束]

path relative(const path& p, system::error_code& ec);

返回:relative(p, current_path(), ec)

引发:  如错误报告中所说明的。

path relative(const path& p, const path& base=current_path());
path relative(const path& p, const path& base, system::error_code& ec);

概述:返回相对于 base 生成的 p。将空路径或相同路径作为特殊情况对待,而不是错误对待。在进行其他处理之前解析符号链接,并标准化 pbase

返回:weakly_canonical(p).lexically_relative(weakly_canonical(base))。如果出现错误,则第二个形式返回 path()

引发:如错误报告中所说明的。

bool remove(const path& p);
bool remove(const path& p, system::error_code& ec);

影响: 如果 exists(symlink_status(p,ec)) 存在,则将它删除,就像由 ISO/IEC 9945 remove()一样。

[注意:删除的是符号链接本身,而不是它解析为的文件。—注释结束]

后置条件:!exists(symlink_status(p))

返回:如果 p 不存在,则返回 false,否则返回true

抛出:错误报告 中所指定。

uintmax_t remove_all(const path& p);
uintmax_t remove_all(const path& p, system::error_code& ec);

影响: 如果 p 存在,则递归删除其内容,然后删除文件 p本身,就像由 ISO/IEC 9945 remove()一样。

[注意:删除的是符号链接本身,而不是它解析为的文件。—注释结束]

后置条件:!exists(p)

返回:已删除文件数量。

抛出:错误报告 中所指定。

void rename(const path& old_p, const path& new_p);
void rename(const path& old_p, const path& new_p, system::error_code& ec);

影响:old_p重命名为 new_p,就像由 ISO/IEC 9945 rename()一样。

[说明:如果 old_pnew_p 解析为同一现有文件,则不执行任何操作。否则,如果 new_p 解析为现有非目录文件,则将其删除,而如果 new_p 解析为现有目录,则如果它在 ISO/IEC 9945 中为空则删除它,但如果在 Windows 中则发生错误。要重命名的不是其解析到的文件,而是符号链接自身。—结束说明]

抛出:错误报告 中所指定。

void resize_file(const path& p, uintmax_t new_size);
void resize_file(const path& p, uintmax_t new_size, system::error_code& ec);

后置条件: file_size() == new_size

抛出:错误报告 中所指定。

备注:通过 ISO/IEC 9945 truncate() 达到其后置条件。

space_info space(const path& p);
space_info space(const path& p, system::error_code& ec);

返回:类型为 space_info 的对象。space_info 对象的值确定为:通过使用 ISO/IEC 9945 statvfs() 来获取 ISO/IEC 9945 结构 statvfs,然后将它的 f_blocksf_bfreef_bavail 成员乘以它的 f_frsize 成员,并将结果分别分配给 capacityfreeavailable 成员。无法确定其值的任何成员都将设置为 -1.

抛出:错误报告 中所指定。

file_status status(const path& p);

影响:好像

system::error_code ec;
file_status result = status(p, ec);
if (result == status_error)
  throw filesystem_error(implementation-supplied-message, p, ec);
return result;

返回:见上文。

引发: filesystem_error。 [说明: resultfile_status(file_not_found)file_status(type_unknown) 值不被视为失败,也不会导致引发异常。—结束说明]

file_status status(const path& p, system::error_code& ec) noexcept;

效果

如果可能,确定文件 p 解析到的属性,就像 ISO/IEC 9945 stat() 一样。

如果在属性确定过程中,底层文件系统 API 报告错误,则将 ec 设置为指明报告的特定错误。否则,ec.clear()

[说明:这允许用户检查底层 API 错误的具体信息,即使 status() 返回的值不是 file_status(status_error)。  —结束说明]

返回

如果 ec != error_code()

[注意:这些语义区分 p 明显不存在、p 存在但无法确定其属性以及存在错误(甚至无法知道 p 是否存在)这几种情况。这些区别对于某些用例很重要。 —注释结束]

否则,

备注:如果在路径名解析期间遇到符号链接,则使用符号链接的内容继续执行路径名解析。

bool status_known(file_status s) noexcept;

返回: s.type() != status_error

file_status symlink_status(const path& p);
file_status symlink_status(const path& p, system::error_code& ec) noexcept;

效果:同上方的 status(),但 p 的属性是通过 ISO/IEC 9945 lstat() 确定的。

返回:同上方的 status(),但如果属性指示为符号链接,如同 ISO/IEC 9945 S_ISLNK(),则返回 file_status(symlink_file)

备注:如果 p 命名为符号链接,则路径名解析终止。

抛出: filesystem_error;使用 error_code& 重载的函数不会抛出任何内容。

path system_complete(const path& p);
path system_complete(const path& p, system::error_code& ec);

效果:使用与操作系统将传递给标准库 open 函数作为 filename 参数的路径解析相同的规则,根据 p 组成一个绝对路径。

返回:组成的路径。

后置条件:对于返回的路径 rprp.is_absolute() 为真。

抛出:错误报告 中所指定。

[注意:对于 ISO/IEC 9945,system_complete(p) 的语义与 absolute(p, current_path()) 相同。

适用于 Windows,如果 p.is_absolute() || !p.has_root_name()pbase 具有相同的 root_name(),则 system_complete(p) 会拥有与 absolute(p, current_path()) 相同的语义。否则,它的行为类似于 absolute(p, kinky),其中 kinkyp.root_name() 驱动器的当前目录。它将成为上次在该驱动器中设置的当前目录,因此可能是 由命令处理器运行的先前程序遗留的残留项!虽然这些语义通常很有用,但它们也非常容易出错。

path temp_directory_path();
path temp_directory_path(system::error_code& ec);

返回:适用于操作系统惯例的临时文件且符合以下条件的目录路径。如何确定此路径的具体细节由实现决定。如果 p 是需要返回的路径,则当 !exists(p) || !is_directory(p) 时应报告错误。

ISO/IEC 9945:由 TMPDIR、TMP、TEMP、TEMPDIR 列表中找到的第一个环境变量提供的路径。如果未找到其中的任何一个,则返回 "/tmp",或者如果已定义宏 __ANDROID__ ,则返回 "/data/local/tmp"

Windows:Windows GetTempPath API 函数报告的路径。

抛出:错误报告 中所指定。

[请注意:选择 temp_directory_path() 名称是为了强调返回结果是一条路径,而不仅仅是一个目录名称。  —结束说明—]

path unique_path(const path& model="%%%%-%%%%-%%%%-%%%%");
path unique_path(system::error_code& ec);
path unique_path(const path& model, system::error_code& ec);

unique_path 函数生成一个适用于创建临时文件(包括目录)的路径名称。此名称基于的模型使用百分号字符来指定由随机十六进制数字替换的位置。如果没有指定模型,则使用等效于 "%%%%-%%%%-%%%%-%%%%" 的默认模型。[请注意:生成路径名称中的随机性越多,它之前存在或被猜到的可能性就越小。模型中的每个替换十六进制数字添加四位的随机性。因此,默认模型提供 64 位的随机性。这足以满足大多数应用程序的需求。 —结束说明—]

返回:一条与 model 完全相同的路径,但百分号字符的每次出现都将被介于 0-9、a-f 之间的随机十六进制数字字符替换。

抛出:错误报告 中所指定。

备注:建议通过 加密安全伪随机数生成器(例如操作系统提供的生成器)来获取必要的随机性。[请注意:在获得足够的熵之前,此类生成器可能会阻塞。 —结束说明—]

path weakly_canonical(const path& p, const path& base=current_path());
path weakly_canonical(const path& p, system::error_code& ec);
path weakly_canonical(const path& p, const path& base, system::error_code& ec);

概述:返回已解析符号链接且已将结果标准化的 p

效果:head成为存在的p的首要元素的路径,让tail成为剩余的p。在未指定时,basecurrent_path()current_path(ec)获取。调用canonical(head, base)canonical(head, base, ec),使用operator/的方式附加tail到返回的路径。随后对结果规范化并返回。

后置条件:返回的路径采用标准格式

备注:使用operator/=组合返回的路径。使用status函数确定是否存在。

备注:建议实现避免不必要的规范化,比如当canonical已在整个p中调用时。

引发:  如错误报告中所说明的。


文件流

<boost/filesystem/fstream.hpp>头文件

提供了 C++ 标准库的<fstream>头文件中的文件流类的替换。这些替代类公开继承自标准库类。在 Boost.Filesystem 版本中,构造函数和 open 函数采用const path&自变量,而非const char*自变量。语法或语义中没有其他差异。

namespace boost
{
  namespace filesystem
  {
    template < class charT, class traits = std::char_traits<charT> >
    class basic_filebuf : public std::basic_filebuf<charT,traits>
    {
    public:
      basic_filebuf<charT,traits>*
        open(const path& p, std::ios_base::openmode mode);
    };

    template < class charT, class traits = std::char_traits<charT> >
    class basic_ifstream : public std::basic_ifstream<charT,traits>
    {
    public:
      explicit basic_ifstream(const path& p, std::ios_base::openmode mode=std::ios_base::in)
      void open(const path& p, std::ios_base::openmode mode=std::ios_base::in);
    };

    template < class charT, class traits = std::char_traits<charT> >
    class basic_ofstream : public std::basic_ofstream<charT,traits>
    {
    public:
      explicit basic_ofstream(const path& p, std::ios_base::openmode mode=std::ios_base::out);
      void open(const path& p, std::ios_base::openmode mode=std::ios_base::out);
    };

    template < class charT, class traits = std::char_traits<charT> >
    class basic_fstream : public std::basic_fstream<charT,traits>
    {
    public:
      explicit basic_fstream(const path& p,
        std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);
      void open(const path& p,
        std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);
    };

    typedef basic_filebuf<char> filebuf;
    typedef basic_ifstream<char> ifstream;
    typedef basic_ofstream<char> ofstream;
    typedef basic_fstream<char> fstream;

    typedef basic_filebuf<wchar_t> wfilebuf;
    typedef basic_ifstream<wchar_t> wifstream;
    typedef basic_fstream<wchar_t> wfstream;
    typedef basic_ofstream<wchar_t> wofstream;

  }  // namespace filesystem
}  // namespace boost

<boost/filesystem/cstdio.hpp>头文件

此头文件提供了 C++ 标准库头文件<cstdio>中的std::fopen重载。重载接受const path&作为其第一个自变量,而非const char*,并且与其标准对应项没有其他差异。

namespace boost
{
  namespace filesystem
  {
    std::FILE* fopen(const path& p, const char* mode);

  }  // namespace filesystem
}  // namespace boost

路径分解表

此表格由使用 Boost 实现编译的程序生成。

阴影部分表示 ISO/IEC 9945 (POSIX) 和 Windows 实现产生不同结果的情况。上方的值是 ISO/IEC 9945 结果,而下方值是 Windows 结果。

构造函数
自变量
迭代

元素
string() generic_
string()
root_
path()
root_
name()
root_
directory()
relative_
path()
parent_
path()
filename()
empty empty empty empty empty empty empty empty empty empty
. . . . empty empty empty . empty .
.. .. .. .. empty empty empty .. empty ..
foo foo foo foo empty empty empty foo empty foo
/ / / / / empty / empty empty /
/foo /,foo /foo /foo / empty / foo / foo
foo/ foo,. foo/ foo/ empty empty empty foo/ foo .
/foo/ /,foo,. /foo/ /foo/ / empty / foo/ /foo .
foo/bar foo,bar foo/bar foo/bar empty empty empty foo/bar foo bar
/foo/bar /,foo,bar /foo/bar /foo/bar / empty / foo/bar /foo bar
//net //net //net //net //net //net empty empty empty //net
//net/foo //net,/,foo //net/foo //net/foo //net/ //net / foo //net/ foo
///foo/// /,foo,. ///foo/// ///foo/// / empty / foo/// ///foo .
///foo///bar /,foo,bar ///foo///bar ///foo///bar / empty / foo///bar ///foo bar
/. /,. /. /. / empty / . / .
./ .,. ./ ./ empty empty empty ./ . .
/.. /,.. /.. /.. / empty / .. / ..
../ ..,. ../ ../ empty empty empty ../ .. .
foo/. foo,. foo/. foo/. empty empty empty foo/. foo .
foo/.. foo,.. foo/.. foo/.. empty empty empty foo/.. foo ..
foo/./ foo,.,. foo/./ foo/./ empty empty empty foo/./ foo/. .
foo/./bar foo,.,bar foo/./bar foo/./bar empty empty empty foo/./bar foo/. bar
foo/.. foo,.. foo/.. foo/.. empty empty empty foo/.. foo ..
foo/../ foo,..,. foo/../ foo/../ empty empty empty foo/../ foo/.. .
foo/../bar foo,..,bar foo/../bar foo/../bar empty empty empty foo/../bar foo/.. bar
c c c c empty
c
empty
c
empty c
empty
empty c
c:/ c:,.
c:,/
c:/ c:/ empty
c:/
empty
c
empty
/
c:/
empty
c .
/
c:foo c:foo
c:,foo
c:foo c:foo empty
c
empty
c
empty c:foo
foo
empty
c
c:foo
foo
c:/foo c:,foo
c:,/,foo
c:/foo c:/foo empty
c:/
empty
c
empty
/
c:/foo
foo
c
c:/
foo
c:foo/ c:foo,.
c:,foo,.
c:foo/ c:foo/ empty
c
empty
c
empty c:foo/
foo/
c:foo .
c:/foo/ c:,foo,.
c:,/,foo,.
c:/foo/ c:/foo/ empty
c:/
empty
c
empty
/
c:/foo/
foo/
c:/foo .
c:/foo/bar c:,foo,bar
c:,/,foo,bar
c:/foo/bar c:/foo/bar empty
c:/
empty
c
empty
/
c:/foo/bar
foo/bar
c:/foo bar
prn prn prn prn empty
prn
empty
prn
empty prn
empty
empty prn
c:\ c:\
c:,/
c:\ c:\
c:/
empty
c:\
empty
c
empty
\
c:\
empty
empty
c
c:\
\
c:foo c:foo
c:,foo
c:foo c:foo empty
c
empty
c
empty c:foo
foo
empty
c
c:foo
foo
c:\foo c:\foo
c:,/,foo
c:\foo c:\foo
c:/foo
empty
c:\
empty
c
empty
\
c:\foo
foo
empty
c:\
c:\foo
foo
c:foo\ c:foo\
c:,foo,.
c:foo\ c:foo\
c:foo/
empty
c
empty
c
empty c:foo\
foo\
empty
c:foo
c:foo\
.
c:\foo\ c:\foo\
c:,/,foo,.
c:\foo\ c:\foo\
c:/foo/
empty
c:\
empty
c
empty
\
c:\foo\
foo\
empty
c:\foo
c:\foo\
.
c:\foo/ c:\foo,.
c:,/,foo,.
c:\foo/ c:\foo/
c:/foo/
empty
c:\
empty
c
empty
\
c:\foo/
foo/
c:\foo .
c:/foo\bar c:,foo\bar
c:,/,foo,bar
c:/foo\bar c:/foo\bar
c:/foo/bar
empty
c:/
empty
c
empty
/
c:/foo\bar
foo\bar
c
c:/foo
foo\bar
bar

Windows 上的长路径和 \\?\ 命名空间前缀

Microsoft Windows 的“最大路径长度限制”规定

在 Windows API 中(有一些例外...),路径的最大长度为 MAX_PATH,它被定义为 260 个字符。

Windows API 有很多函数也有 Unicode 版本,允许使用扩展长度路径,以实现 32,767 个字符的最大总路径长度。...要指定扩展长度路径,请使用“\\?\”前缀。例如,“\\?\D:\非常长的路径”。 [C++ 字符串文本当然需要斜杠加倍。]

因为大多数 Boost.Filesystem 运行函数只是将类路径对象的内容传递给 Windows API,所以它们确实可以与扩展长度前缀一起使用。但由于 Windows 施加的限制,一些函数将不起作用。

实际上,“\\?\”前缀会通知底层 Windows API,路径标识了 Win32 文件系统命名空间中的一个对象,并且禁用了 Windows API 的大多数内部路径处理,包括规范化。虽然它取消了长度限制,但这对可接受路径施加了以下部分列出的许多其他限制。还有许多其他具有不同特殊含义的前缀,例如“\\.\"(本地设备命名空间前缀)和“\??\”(NT 对象命名空间前缀)。请注意,可以通过引用特殊“UNC”设备使用前缀来扩展 UNC 路径。例如,“\\server\share”可以扩展为“\\?\UNC\server\share”。

就 Boost.Filesystem 而言,命名空间前缀被视为路径的根名称的一部分。例如,“\\?\c:\foo”的根名称是“\\?\c:”。选择此解释是为了允许根路径是可迭代的,也就是说你可以列出“\\?\c:\”目录的内容,前提是存在 C 盘并且你有必要的权限。[注:你无法列出“\\?\"的内容,因为该路径不存在。]

带有命名空间前缀的路径的注意事项

致谢

此文件系统库献给我妻子桑达,她提供了必要的支持,让我得以看到试验性实现和提议本身完成。在我经历了一年艰难的癌症治疗期间,她给了我继续前进的力量。

许多人向 Boost 文件系统库贡献了技术评论、想法和建议。请参见 版本历史记录

Dietmar Kühl 提供了最初的 Boost 文件系统库 directory_iterator 设计。Peter Dimov、Walter Landry、Rob Stewart 和 Thomas Witt 尤其有助于完善该库。

create_directoriesextensionbasenamereplace_extension 功能由 Vladimir Prus 开发。temp_directory_path 功能由 Jeff Flinn 提供。David Svoboda 建议使用 canonical 功能并提供了伪代码。

Howard Hinnant 和 John Maddock 审阅了版本 2 提案的草案,并发现了一些错误或缺点,从而产生了更为完善的最终文档。

Peter Dimov 建议使用一个类 path,以及成员模板以适应多种字符串类型。他的主意成为了版本 3 路径设计的依据。

参考

[ISO/IEC 9945] ISO/IEC 9945:2003、IEEE Std 1003.1-2001,以及 The Open Group Base Specifications,第 6 版。也称为《单一 UNIX® 规范》,第 3 版。可以从参与其创建的每个组织获得。例如,可以从 www.unix.org/single_unix_specification/ 在线阅读或下载。ISO JTC1/SC22/WG15 - POSIX 主页为 www.open-std.org/jtc1/sc22/WG15/
[Abrahams] Dave Abrahams,错误和异常处理,www.boost.org/more/error_handling.html

© Copyright Beman Dawes,2002、2006、2007、2009、2010、2011

© Copyright Andrey Semashev,2019-2024

根据 Boost 软件许可证,第 1.0 版发布。请参阅 www.boost.org/LICENSE_1_0.txt