文件系统库 版本 4 |
主页 教程 参考 常见问题解答 版本 可移植性 V4 V3 简介 V3 设计 不推荐使用 错误报告 |
本参考文档描述了 C++ 程序在涉及到文件系统(包括路径、常规文件和目录)时可能使用的组件。
本参考文档中的一些行为是通过参考 ISO/IEC 9945 来指定的。实际如何实现此类行为并没有提及。
[注意:这是一个用于实现依赖于操作系统的行为的“好像”规则。实际上,实现通常会调用本机操作系统的 API。—结束注释]
建议实现提供 ISO/IEC 9945 定义的行为。实现应记录与 ISO/IEC 9945 定义的行为不同的任何行为。鼓励不支持精确的 ISO/IEC 9945 行为的实现尽可能提供接近 ISO/IEC 9945 行为的行为,但要受实际操作系统和文件系统的限制。如果某个实现无法提供任何合理的行为,该实现应以实现定义的方式报告错误。
[注意:此类错误可能通过以下方式报告:
#error
指令、static_assert
、filesystem_error
异常、特殊返回值或其他方式。—结束注释]
实现不需要提供特定文件系统不支持的行为。
[示例:某些存储卡、照相机内存和软盘使用的 FAT 文件系统 不支持硬链接、符号链接等很多更高级文件系统支持的功能。实现只需要支持由主机操作系统支持的 FAT 功能。—结束示例]
在此参考中描述的函数的行为可能与其在存在文件系统竞争情况下的规范不同。不要求进行诊断。
如果文件系统竞争的可能性会使程序在调用此参考文档中描述的函数之前无法可靠地测试先决条件,则不会为该条件指定Requires。相反,该条件指定为Throws条件。
[注意:作为设计实践,当程序在调用函数之前检测到先决条件是不合理时,不会指定先决条件。——注意结束]
在此参考文档中指定某些行为与操作系统相关 ([fs.def.osdep])。取决于其实现的操作系统是由实现定义的。
允许实现依赖于操作系统模拟器,而不是实际操作系统。
[示例:某个实现使用 Cygwin,这是一种面向某些 Windows® 操作系统版本的 Linux® API 模拟器。该实现将 Cygwin 定义为其操作系统。用户可以参考 Cygwin 文档以找到操作系统相关行为的详细信息。——示例结束]
用户和符合性测试能够检测出此类实现是在 Cygwin 中运行的。如果实现将 Linux 或 Windows 定义为操作系统而不是 Cygwin,用户会误以为该实现是 Linux 或 Windows,并且符合性测试会失败,因为实际行为融合了这两者。
以下定义适用于整个参考文档
依赖于操作系统行为和特性的行为。请参阅 [fs.conform.os]。
可以写入、读取或同时写入和读取的对象。文件具有一些属性,包括类型。文件类型包括常规文件和目录。实现可能支持其他类型的文件,例如符号链接。
文件集合及其某些属性。
文件名称。文件名 "."
和 ".."
具有特殊含义。文件名的以下特性与操作系统相关
允许的字符。请参阅 [fs.os.examples]。
不允许的特定文件名。
具有特殊含义的其他文件名。
在路径解析期间的大小写识别和敏感性。
可能适用于非常规文件(例如目录)的其他文件类型所适用的特殊规则。
一个序列的元素会确定文件在文件系统中的位置。这些元素有 root-nameopt、 root-directoryopt,以及一个可选的文件名序列。 [注意: pathname 是路径的具体展示。 —结束注]
一种明确标识文件位置的路径,而无需提及额外的起始位置。路径的决定它是绝对路径的元素会根据不同的操作系统确定。
一种不是绝对路径的路径,因此只会根据一个隐含的起始位置进行明确标识文件位置。路径的决定它是相对路径的元素会根据不同的操作系统确定。 [注意: 路径 "."
和 ".."
是相对路径。 —结束注]
没有符号连接元素以及没有 "."
或 ".."
元素的绝对路径。
表示路径名的一个字符字符串。路径名会根据通用路径名语法或一个操作系统相关的原生路径名格式进行格式化。
由主机操作系统所接受的操作系统相关路径名格式。
没有冗余目录分隔符、当前目录 (dot) 或父目录 (dot-dot) 元素的路径。空路径的常规形式也是空路径。 [v3: 以不是根目录的 directory-separator 结尾的路径的常规形式是相同路径,后加一个当前目录 (dot) 元素]
将文件名与文件相关联的目录条目对象。在某些文件系统中,一些目录条目会将名称与相同文件相关联。
一个现有文件的连接。某些文件系统支持多个硬连接到一个文件。如果文件的所有硬连接都被移除,文件本身将会被移除。
[注意: 硬连接可以看成是用于文件的共享所有权智能指针。 —结束注]
一种文件类型,当在路径名解析期间遇到文件时,文件储存在的字符串会用来修改路径名解析。
[注意: 符号连接可以看成指向文件的原始指针。如果指针所指向的文件不存在,则该符号连接被称为“悬空”符号连接。 —结束注]
在文件系统中,多个线程、进程或计算机交错访问和修改同一对象时发生的条件。
路径名
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 可能对特定操作系统具有特殊意义。
该参考文档中将某些特性指定为与操作系统相关。下表显示了将这些规范应用于使用 ISO/IEC 9945 或 Windows® 应用程序接口 (API) 的操作系统的示例。[脚注 1]
特性 |
部分 |
ISO/IEC 9945 |
Windows® API |
注释 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
不需要 |
不需要 |
对于这些操作系统,无需区分通用格式和本机格式。 |
|
|
不执行转换 |
不执行转换 |
通用格式已经适用于这些操作系统本身的 API 了。 |
|
|
|
|
这些操作系统接受目录名和最终文件名之间的相同本机分隔符,因此无需执行格式转换。其他操作系统可能需要转换。 |
|
由 |
不执行转换 |
不执行转换 |
为了提高效率,无论操作系统如何, |
|
由 |
不执行转换 |
反斜杠转换为斜杠 |
|
|
|
不更改 |
斜杠转换为反斜杠 |
|
|
文件名中禁止使用的字符 |
0x00、 |
0x00-0x1F、 |
许多操作系统禁止在文件名中使用 ASCII 控制字符 (0x00-0x1F)。 |
|
初始的 imbue 的 |
|
实现提供的语言环境,如果 |
Apple OS X®: 实现提供的语言环境,提供 UTF-8 |
[脚注 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
文件系统库函数通常有两种重载形式,一种是抛出异常以报告文件系统错误,另一种是设置一个error_code
。
[注意: 这支持两种常见用例
用例:文件系统错误确实很罕见且表示发生严重故障。抛出异常是最合适的响应。对于大多数日常编程而言,这是首选默认选项。
用例:文件系统错误是常规性的,不一定表示发生故障。返回一个错误代码是最合适的响应。这允许进行特定于应用程序的错误处理,包括直接忽略错误。
—结束注释]
以下函数没有 type 为 system::error_code&
的参数,会以如下方式报告错误,除非另有指定
当实现对操作系统或其他底层 API 的调用产生错误,而该错误阻止函数满足其规范时,将抛出 type 为 filesystem_error
的异常。
未成功分配存储空间会抛出异常,如 C++ 标准 17.6.4.10 [res.on.exception.handling] 所述。
析构函数不抛出任何内容。
以下函数具有 type 为 system::error_code&
的参数,会以如下方式报告错误,除非另有指定
如果实现对操作系统或其他底层 API 的调用产生错误,而该错误阻止函数满足其规范,则会对 system::error_code&
参数进行设置,以适合特定的错误。否则,将对 system::error_code&
参数调用 clear()
。
未成功分配存储空间会抛出异常,如 C++ 标准 17.6.4.10 [res.on.exception.handling] 所述。
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] 也适用。 —结束注释]
至少到 2012 版本的 Visual C++ 没有使用 C++11 风格的静态初始化锁定,因此 path::codecvt()
的初始化可以触发竞争,如果从不同线程调用 path::imbue()
也可能会触发。一个变通办法是调用
path::codecvt(); // 确保 VC++ 不会在初始化过程中发生竞争。
在启动任何其他线程之前,在主线程中。 [注意: Filesystem 实现执行锁定的显式修复不起作用,因为 Microsoft 编译器存在不相关的其他问题;对于静态链接,运行时尝试在 main() 开始之前进行初始化,但在那时不允许操作系统锁定调用。 —结束注释]
在使用环境变量确定路径编码的 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
兼容迭代器的要求。迭代器的值类型需要是以下之一:char
、wchar_t
。统称为这些类型受支持的路径字符类型。
指定为 Source
的模板参数需要是以下之一
std::basic_string
、std::basic_string_view
、boost::container::basic_string
或 boost::basic_string_view
专门,且值类型为受支持的路径字符类型之一。
v3,已弃用:值类型为受支持的路径字符类型之一的容器。
包含以空结尾的字符串的指针。值类型需要是一个受支持的路径字符类型。
包含以空结尾的字符串的受支持的路径字符类型的 C 数组。
一个 boost::filesystem::directory_entry
。
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());
作用:将
pathname
中source
的内容 [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());
作用:将
pathname
中source
或p
的内容 [begin
,end
) 存储在,在需要时转换格式和编码 ([path.arg.convert])。返回:
*this
path
追加 [path.append]追加操作使用 operator/=
来表示所需时追加“首选分隔符”的语义效果。
path& operator/=(const path& p); path& append(const path& p);
效果
v3: 追加
path::preferred_separator
至pathname
,在需要时转换格式和编码 ([path.arg.convert]),除非
添加的分隔符为多余项,或
将相对于路径更改为绝对路径,或
p.empty()
,或
*p.native().cbegin()
是一个目录分隔符。然后将
p.native()
追加至pathname
。v4: 如果
p.is_absolute() || (p.has_root_name() && p.root_name() != root_name())
,将p
赋值给*this
。否则,修改*this
,如同以下步骤
- 如果
p.has_root_directory()
,删除根目录和相对路径(如果存在)。- 令
x
为一个内容为p
但没有根名的path
。如果has_filename()
为true
,且x
并未以目录分隔符开头,则追加path::preferred_separator
。- 附加
x.native()
。[注释:路径是绝对路径还是相对路径取决于目标操作系统的约定。因此,对于某些路径,追加操作的结果对于不同的操作系统而言可能不同。例如,对于 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
是
如果
p
存在且为const path&
,则为p.native()
,否则为
s
,其中s
是std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
,如果
s(begin, end)begin
和end
参数存在,否则为
x
.如果
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());
效果
从存储的路径中删除所有现有的
extension()
,然后当且仅当
new_extension
不为空且不以句点字符开头时,将句点字符附加到存储的路径,然后将
new_extension
附加到存储的路径。返回值:
*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
。将空或相同路径视为特殊情况,而非错误。不会解析符号链接。不会先对*this
或base
进行规范化。备注:使用
std::mismatch(begin(), end(), base.begin(), base.end())
确定*this
和base
中不匹配的第一个元素。使用operator==
确定元素是否匹配。返回
path()
,如果*this
的第一个不匹配元素等于begin()
或base
的第一个不匹配元素等于base.begin()
;或者
path(".")
,如果*this
的第一个不匹配元素等于end()
,base
的第一个不匹配元素等于base.end()
;或者
- 类
path
的对象,通过对半开区间 [base
中不匹配的第一个元素,base.end()
) 中的每个元素应用operator/= path("..")
,再对半开区间 [*this
中不匹配的第一个元素,end()
) 中的每个元素应用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
—注释结束][注意:如果需要 规范化 来确保元素匹配一致,请对
*this
、base
或两者应用lexically_normal()
。 —注释结束]
path lexically_proximate(const path& base) const;
返回:如果
lexically_relative(base)
返回非空路径,则返回该路径。否则,返回*this
。[注意:如果需要符号链接后续语义,请使用操作函数
relative
—注释结束][注意:如果需要 规范化 来确保元素匹配一致,请对
*this
、base
或两者应用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。备注:元素的判断方法如下:对于
*this
和p
,迭代半开范围 [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]路径迭代器 iterator
、const_iterator
、reverse_iterator
和 const_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
。备注:如果两个序列具有相同数量的元素,并且其相应的元素相等,则两个序列都不是按词法小于另一个序列。如果一个序列是另一个序列的前缀,则较短的序列按词法小于较长的序列。否则,序列的词法比较产生的结果与第一个不相同的相应元素对的比较结果相同。
[注释:出于历史原因,提供基于
path
的lexicographical_compare
算法。—注释结束]
path lexically_normal(const path& p);
概述:返回经过移除冗余当前目录(dot)、父目录(dot-dot)和 目录分隔符 元素的
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
变为相对路径。将空或相同路径视为特殊情况,而不是错误。不解析符号链接。不会首先对p
或base
进行标准化。备注:使用
std::mismatch(p.begin(), p.end(), base.begin(), base.end())
确定p
和base
的第一个不匹配元素。使用operator==
判断元素是否匹配。返回
如果
p
的第一个不匹配元素等于p.begin()
或base
的第一个不匹配元素等于base.begin()
,则返回path()
,或者
如果
p
的第一个不匹配元素等于p.end()
且base
的第一个不匹配元素等于base.end()
,则返回path(".")
,或者
通过对半开区间 [
base
的第一个不匹配元素,base.end()
) 中的每个元素应用operator/= path("..")
,然后对半开区间 [p
的第一个不匹配元素,p.end()
)] 中的每个元素应用operator/=
来组合出类path
的一个对象。[示例:
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()
包装p
、base
或两者。—注释结束]
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
一个双引号。
p.string<std::basic_string<Char>>()
中的每个字符。如果待插入的字符与由operator==
判定的转义字符或双引号相等,请首先插入转义字符。一个双引号。
[注意: 影响类似于
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 提取字符
- 如果待提取的第一个字符与由
operator==
判定的双引号相等,则
- 丢弃初始的双引号。
- 保存该值,然后关闭
skipws
标记。p.clear()
- 在未转义的双引号字符出现之前或
is.not_good()
之前, 从is
提取字符并将其附加到p
,但如果达到转义字符,请忽略它并将下一个字符附加到p
。- 丢弃最终的双引号字符。
- 将
skipws
标记还原为其原始值。- 否则,
is >> p
。[注意: 影响类似于
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()
w
hat_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()
字符串在返回字符串中。
此枚举指定用于识别文件类型的常量。
常量名称 | 含义 |
status_error |
尝试获取文件状态时出错。简单地找不到文件并非被视为状态错误。 |
file_not_found |
找不到文件 |
regular_file |
普通文件 |
directory_file |
目录文件 |
symlink_file |
符号链接文件 |
block_file |
块特殊文件 |
character_file |
字符特殊文件 |
fifo_file |
FIFO 或管道文件 |
socket_file |
套接字文件 |
type_unknown |
文件存在,但属于上述任何情况中未涵盖的特定于系统的类型。 |
此 enum
指定用于识别文件权限的位掩码常量。ISO/IEC 9945 (POSIX) 指定实际值,并且此处已采用这些值,因为它们对许多 POSIX 用户非常熟悉并根深蒂固。
Windows:目前会忽略除了写之外的所有权限。只有一个写权限;为所有者、组或其他人设置写权限会设置所有人的写权限,而移除所有者、组或其他人的写权限会移除所有人的写权限。
名称 | 值 (八进制) |
ISO/IEC 9945 宏 |
定义或注释 |
| 0 | 未为文件设置任何权限。注意:file_not_found 是 no_perms 而不是 perms_not_known |
|
owner_read | 0400 | S_IRUSR |
所有者的读取权限 |
owner_write | 0200 | S_IWUSR |
所有者的写入权限 |
owner_exe | 0100 | S_IXUSR |
所有者的执行/搜索权限 |
owner_all | 0700 | S_IRWXU |
所有者的读取、写入、执行/搜索权限;owner_read | owner_write | owner_exe |
group_read | 040 | S_IRGRP |
组的读取权限 |
group_write | 020 | S_IWGRP |
组的写入权限 |
group_exe | 010 | S_IXGRP |
组的执行/搜索权限 |
group_all | 070 | S_IRWXG |
组的读取、写入、执行/搜索权限;group_read | group_write | group_exe |
others_read | 04 | S_IROTH |
其他人的读取权限 |
others_write | 02 | S_IWOTH |
其他人的写入权限 |
others_exe | 01 | S_IXOTH |
其他人的执行/搜索权限 |
others_all | 07 | S_IRWXO |
其他人的读取、写入、执行/搜索权限;others_read | others_write | others_exe |
all_all | 0777 | owner_all | group_all | others_all |
|
set_uid_on_exe | 04000 | S_ISUID |
在执行时设置用户 ID |
set_gid_on_exe | 02000 | S_ISGID |
执行时设置组 ID |
sticky_bit | 01000 | S_ISVTX |
取决于操作系统。本身不可移植,甚至在 ISO/IEC 9945 操作系统之间。 |
perms_mask | 07777 | all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit |
|
perms_not_known | 0xFFFF | 权限未知,例如在没有指定权限的情况下创建 file_status 对象时 |
|
| 0x1000 |
|
|
remove_perms | 0x2000 |
permissions() 从文件的当前位中移除自变量权限位 |
|
symlink_perms | 0x4000 |
在 ISO/IEC 9945 permissions() 解析符号链接,除非指定了 symlink_perms 。在 Windows 中, permissions() 永远不会解析符号链接,因此毫无意义。由于 permissions() 始终解析符号链接,因此在 Mac OS X 和一些其他 BSD 系统中毫无意义。不要纠结。 |
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_error
,permissions() == perms_not_known
。
explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;
后置条件:
type() == ft
,permissions() == 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_status
和m_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_status
和m_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_status
和m_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 9945readdir_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
进行递增,会导致该目录自身被迭代,这是由 operator++
和 increment
函数指定的。recursive_directory_iterator
迭代到当前正在迭代的目录末尾,或者调用 pop()
时,m_depth
会减少,并且对父目录的迭代会继续。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
参数的签名,假定opts
是directory_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() && is_directory(this->status()) && (!is_symlink(this->symlink_status()) || (m_options & directory_options::follow_directory_symlink) != 0)
那么
打开目录
(*this)->path()
并递归迭代到其中,m_depth
增加;如果使用
permission_denied
错误打开目录失败并且(m_options & directory_options::skip_permission_denied) != 0
,则对当前层上的迭代器进行增加并忽略错误(操作成功完成)。- 如果此层没有更多目录条目,那么
m_depth
就会减少,并且对父目录的迭代就会恢复。如果操作完成时出现错误,那么
- 如果
(m_options & directory_options::pop_on_error) != 0
,则将迭代器保留为反复调用pop()
后的状态,直到成功或迭代器等于尾部迭代器;任何pop()
失败都不会向调用者报告;- 否则,迭代器将被设置为等于尾部迭代器。
后置条件:
recursion_pending() == true
。返回值:
*this
。抛出:如 错误报告 中所指定。
void pop(); void pop(system::error_code& ec);
要求:
*this != recursive_directory_iterator()
。效果:如果
depth() == 0
,将*this
设置为recursive_directory_iterator()
。否则,--m_depth
将停止迭代当前正在迭代的目录,并继续迭代父目录。如果操作完成时出现错误,那么
- 如果
(m_options & directory_options::pop_on_error) != 0
,则将迭代器保留为反复调用pop()
后的状态,直到成功或迭代器等于尾部迭代器;任何pop()
失败都不会向调用者报告;- 否则,迭代器将被设置为等于尾部迭代器。
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()
。
操作函数查询或修改外部存储中的文件,包括目录。
操作函数通过将 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
参数的重载,base
为current_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
参数的重载,base
为current_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
最多包含以下各组中的一个选项
copy_options::skip_existing
、copy_options::overwrite_existing
或copy_options::update_existing
;copy_options::synchronize_data
或copy_options::synchronize
;copy_options::ignore_attribute_errors
;copy_options::recursive
;copy_options::copy_symlinks
或copy_options::skip_symlinks
;copy_options::directories_only
、copy_options::create_symlinks
或copy_options::create_hard_links
。效果: 令
f
和t
为通过以下方式获取的file_status
对象然后,如果出现以下情况,则报告错误
- 如果
(options & (copy_options::create_symlinks | copy_options::skip_symlinks)) != copy_options::none
,则f = symlink_status(from)
且t = symlink_status(to)
;- 否则,如果
(options & copy_options::copy_symlinks) != copy_options::none
,则f = symlink_status(from)
且t = status(to)
;- 否则,
f = status(from)
且t = status(to)
。否则,如果
!exists(f)
,或者equivalent(from, to)
,或者is_other(f) || is_other(t)
,或者is_directory(f) && is_regular_file(t)
.is_symlink(f)
,则否则,如果
- 如果
(options & copy_options::skip_symlinks) != copy_options::none
,则返回;- 否则,如果
!exists(t) && (options & copy_options::copy_symlinks) != copy_options::none
,则copy_symlink(from, to)
;- 否则报告错误。
is_regular_file(f)
,则否则,如果
- 如果
(options & copy_options::directories_only) != copy_options::none
,则返回;- 否则,如果
(options & copy_options::create_symlinks) != copy_options::none
,则create_symlink(link, to)
,其中link
的确定方式如下- 否则,如果
(options & copy_options::create_hard_links) != copy_options::none
,则create_hard_link(from, to)
;- 否则,如果
is_directory(t)
,则copy_file(from, to / from.filename(), options)
;- 否则
copy_file(from, to, options)
。is_directory(f)
,则否则,对于
- 如果
(options & copy_options::create_symlinks) != copy_options::none
,则报告错误,错误代码等于make_error_code(system::errc::is_a_directory)
;- 否则,如果
则
(options & copy_options::recursive) != copy_options::none
,或options == copy_options::none
且此对copy
的调用不是来自copy
的递归调用,
- 如果
!exists(t)
,则create_directory(to, from)
。- 然后,在
from
中循环处理文件,对于在迭代期间获得的每个directory_entry x
,调用copy(x.path(), to / x.path().filename(), options)
。- 否则,返回。
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
最多包含以下各组中的一个选项
copy_options::skip_existing
、copy_options::overwrite_existing
或copy_options::update_existing
;copy_options::synchronize_data
或copy_options::synchronize
;copy_options::ignore_attribute_errors
.作用:在以下情况下报错
否则,在以下情况下成功返回,且无作用
!is_regular_file(from)
,或exists(to) && !is_regular_file(to)
,或exists(to) && equivalent(from, to)
,或exists(to) && (options & (copy_options::skip_existing | copy_options::overwrite_existing)) == copy_options::none
.否则
exists(to) && (options & copy_options::skip_existing) != copy_options::none
,或exists(to) && (options & copy_options::update_existing) != copy_options::none
并且to
的最后写入时间晚于from
的最后写入时间。
- 文件
from
所解析到的内容和属性会被复制到文件to
所解析到的内容。如果复制文件属性(但不是内容)时由于错误而失败,并且(options & copy_options::ignore_attribute_errors) != copy_options::none
,那么该错误会被忽略。在该错误被忽略之后,- 如果
(options & copy_options::synchronize) != copy_options::none
,已写入数据和属性将与永久存储同步;否则- 如果
(options & copy_options::synchronize_data) != copy_options::none
,已写入数据将与永久存储同步。返回:如果在不报错的情况下成功复制文件,则返回
true
,否则返回false
。抛出:如 错误报告 中所指定。
[注意:当指定了
copy_options::update_existing
时,检查from
和to
的写入时间不一定和复制操作同时进行。在检查了文件修改时间后但在复制开始之前,另一个进程可能会创建或修改由to
标识的文件。在这种情况下,目标文件会被覆盖。][注意:
copy_options::synchronize_data
和copy_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 9945mkdir()
),建立后置条件。对于没有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()
,来建立后置条件。后置条件
exists(to) && exists(
new_hard_link
) && equivalent(to,
new_hard_link
)
- 文件或目录
to
解析到的内容保持不变。抛出:如 错误报告 中所指定。
[注意:某些操作系统根本不支持硬链接,或只支持正规文件的硬链接。某些文件系统不支持硬链接,而不考虑操作系统 - 例如存储卡和闪存驱动器上使用的 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);
返回值:如果
p1
和p2
解析为同一文件系统实体,则返回true
,否则返回false
。如果两个候选实体位于相同位置的同一设备上,则两个路径会被视为解析为同一文件系统实体。这由 ISO/IEC 9945
stat
结构(类似于通过stat()
获得的两个路径的st_dev
和st_ino
值相等)的值确定。[注:ISO/IEC 9945 要求“st_dev 在本地区域网络中必须是唯一的”。保守的 ISO/IEC 9945 实现还可能会检查相等的
st_size
和st_mtime
值。Windows 实现可能会使用GetFileInformationByHandle()
作为stat()
的替代品,并在dwVolumeSerialNumber
、nFileIndexHigh
、nFileIndexLow
、nFileSizeHigh
、nFileSizeLow
、ftLastWriteTime.dwLowDateTime
和ftLastWriteTime.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 9945stat
结构成员st_size
的值确定,类似于通过 ISO/IEC 9945stat()
获得)。否则,返回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 9945stat()
确定。抛出:如 错误报告 中所指定。
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 9945stat()
后跟 ISO/IEC 9945utime()
。抛出:如 错误报告 中所指定。
[注意:未指定
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 9945fchmodat()
一样。有效权限位由下表中指定内容决定。
prms
中存在的位应用的有效位 add_perms
和remove_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
。将空路径或相同路径作为特殊情况对待,而不是错误对待。在进行其他处理之前解析符号链接,并标准化p
和base
。返回:
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 9945remove()
一样。[注意:删除的是符号链接本身,而不是它解析为的文件。—注释结束]
后置条件:
!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 9945remove()
一样。[注意:删除的是符号链接本身,而不是它解析为的文件。—注释结束]
后置条件:
!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 9945rename()
一样。[说明:如果
old_p
和new_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 9945statvfs()
来获取 ISO/IEC 9945 结构statvfs
,然后将它的f_blocks
、f_bfree
和f_bavail
成员乘以它的f_frsize
成员,并将结果分别分配给capacity
、free
和available
成员。无法确定其值的任何成员都将设置为 -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
。 [说明:result
的file_status(file_not_found)
和file_status(type_unknown)
值不被视为失败,也不会导致引发异常。—结束说明]
file_status status(const path& p, system::error_code& ec) noexcept;
效果
如果可能,确定文件
如果在属性确定过程中,底层文件系统 API 报告错误,则将p
解析到的属性,就像 ISO/IEC 9945stat()
一样。ec
设置为指明报告的特定错误。否则,ec.clear()
。[说明:这允许用户检查底层 API 错误的具体信息,即使
status()
返回的值不是file_status(status_error)
。 —结束说明]返回
如果
ec != error_code()
- 如果特定错误指示无法解析
p
,因为路径的某些元素不存在,则返回file_status(file_not_found)
。 [说明: ISO/IEC 9945 中指明此情况的错误为 ENOENT 或 ENOTDIR。Windows 等价项包括 ERROR_FILE_NOT_FOUND、ERROR_PATH_NOT_FOUND、ERROR_INVALID_NAME、ERROR_INVALID_PARAMETER、ERROR_BAD_PATHNAME 和 ERROR_BAD_NETPATH。-- 结束说明]
- 否则,如果特定错误指示可以解析
p
,但无法确定属性,则返回file_status(type_unknown)
。 [说明:例如,Windows ERROR_SHARING_VIOLATION 错误。对于 ISO/IEC 9945 来说,这种情况永远不会出现。—结束说明]
- 否则,返回
file_status(status_error)
。[注意:这些语义区分
p
明显不存在、p
存在但无法确定其属性以及存在错误(甚至无法知道p
是否存在)这几种情况。这些区别对于某些用例很重要。 —注释结束]否则,
- 如果属性指示为常规文件,如同 ISO/IEC 9945 S_ISREG(),则返回
file_status(regular_file)
。 [注意:regular_file
暗示适当的<fstream>
操作会成功,此处假设不存在硬件、权限、访问或文件系统竞争错误。没有regular_file
并不一定意味着<fstream>
操作在目录中会失败。—注释结束]
- 否则,如果属性指示为目录,如同 ISO/IEC 9945 S_ISDIR(),则返回
file_status(directory_file)
。 [注意:directory_file
暗示directory_iterator(p)
会成功。—注释结束]
- 否则,如果属性指示为块特殊文件,如同 ISO/IEC 9945 S_ISBLK(),则返回
file_status(block_file)
。
- 否则,如果属性指示为字符特殊文件,如同 ISO/IEC 9945 S_ISCHR(),则返回
file_status(character_file)
。
- 否则,如果属性指示为 FIFO 或管道文件,如同 ISO/IEC 9945 S_ISFIFO(),则返回
file_status(fifo_file)
。
- 否则,如果属性指示为套接字,如同 ISO/IEC 9945 S_ISSOCK(),则返回
file_status(socket_file)
。
- 否则,返回
file_status(type_unknown)
。备注:如果在路径名解析期间遇到符号链接,则使用符号链接的内容继续执行路径名解析。
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(),但如果属性指示为符号链接,如同 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
组成一个绝对路径。返回:组成的路径。
后置条件:对于返回的路径
rp
,rp.is_absolute()
为真。抛出:如 错误报告 中所指定。
[注意:对于 ISO/IEC 9945,
system_complete(p)
的语义与absolute(p, current_path())
相同。适用于 Windows,如果
p.is_absolute() || !p.has_root_name()
或p
和base
具有相同的root_name()
,则system_complete(p)
会拥有与absolute(p, current_path())
相同的语义。否则,它的行为类似于absolute(p, kinky)
,其中kinky
是p.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
。在未指定时,base
从current_path()
或current_path(ec)
获取。调用canonical(head, base)
或canonical(head, base, ec)
,使用operator/
的方式附加tail
到返回的路径。随后对结果规范化并返回。后置条件:返回的路径采用标准格式。
备注:使用
operator/=
组合返回的路径。使用status
函数确定是否存在。备注:建议实现避免不必要的规范化,比如当
canonical
已在整个p
中调用时。引发: 如错误报告中所说明的。
提供了 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
此头文件提供了 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_ |
root_ |
root_ |
root_ |
relative_ |
parent_ |
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 |
emptyc |
emptyc |
empty | c empty |
empty | c |
c:/ |
c:,. c:,/ |
c:/ |
c:/ |
emptyc:/ |
emptyc |
empty/ |
c:/ empty |
c |
. / |
c:foo |
c:foo c:,foo |
c:foo |
c:foo |
emptyc |
emptyc |
empty | c:foo foo |
emptyc |
c:foo foo |
c:/foo |
c:,foo c:,/,foo |
c:/foo |
c:/foo |
emptyc:/ |
emptyc |
empty/ |
c:/foo foo |
c c:/ |
foo |
c:foo/ |
c:foo,. c:,foo,. |
c:foo/ |
c:foo/ |
emptyc |
emptyc |
empty | c:foo/ foo/ |
c:foo |
. |
c:/foo/ |
c:,foo,. c:,/,foo,. |
c:/foo/ |
c:/foo/ |
emptyc:/ |
emptyc |
empty/ |
c:/foo/ foo/ |
c:/foo |
. |
c:/foo/bar |
c:,foo,bar c:,/,foo,bar |
c:/foo/bar |
c:/foo/bar |
emptyc:/ |
emptyc |
empty/ |
c:/foo/bar foo/bar |
c:/foo |
bar |
prn |
prn |
prn |
prn |
emptyprn |
emptyprn |
empty | prn empty |
empty | prn |
c:\ |
c:\ c:,/ |
c:\ |
c:\ c:/ |
emptyc:\ |
emptyc |
empty\ |
c:\ empty |
emptyc |
c:\ \ |
c:foo |
c:foo c:,foo |
c:foo |
c:foo |
emptyc |
emptyc |
empty | c:foo foo |
emptyc |
c:foo foo |
c:\foo |
c:\foo c:,/,foo |
c:\foo |
c:\foo c:/foo |
emptyc:\ |
emptyc |
empty\ |
c:\foo foo |
emptyc:\ |
c:\foo foo |
c:foo\ |
c:foo\ c:,foo,. |
c:foo\ |
c:foo\ c:foo/ |
emptyc |
emptyc |
empty | c:foo\ foo\ |
emptyc:foo |
c:foo\ . |
c:\foo\ |
c:\foo\ c:,/,foo,. |
c:\foo\ |
c:\foo\ c:/foo/ |
emptyc:\ |
emptyc |
empty\ |
c:\foo\ foo\ |
emptyc:\foo |
c:\foo\ . |
c:\foo/ |
c:\foo,. c:,/,foo,. |
c:\foo/ |
c:\foo/ c:/foo/ |
emptyc:\ |
emptyc |
empty\ |
c:\foo/ foo/ |
c:\foo |
. |
c:/foo\bar |
c:,foo\bar c:,/,foo,bar |
c:/foo\bar |
c:/foo\bar c:/foo/bar |
emptyc:/ |
emptyc |
empty/ |
c:/foo\bar foo\bar |
c c:/foo |
foo\bar bar |
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 盘并且你有必要的权限。[注:你无法列出“\\?\"的内容,因为该路径不存在。]
create_directory(“a”)
这样的简单操作,如果生成目录的绝对路径超过 260 个字符,也会失败。此文件系统库献给我妻子桑达,她提供了必要的支持,让我得以看到试验性实现和提议本身完成。在我经历了一年艰难的癌症治疗期间,她给了我继续前进的力量。
许多人向 Boost 文件系统库贡献了技术评论、想法和建议。请参见 版本历史记录。
Dietmar Kühl 提供了最初的 Boost 文件系统库 directory_iterator
设计。Peter Dimov、Walter Landry、Rob Stewart 和 Thomas Witt 尤其有助于完善该库。
create_directories
、extension
、basename
和 replace_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