百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

c++ filesystem详解(3) - 路径 c++文件路径格式

liebian365 2024-10-27 13:17 22 浏览 0 评论

路径是非常重要的概念, filesystem 提供了path类, 下面学习及解析。

c++ filesystem详解(1) - 概念

c++ filesystem详解(2) - 目录

1. 问题

在工作中, 跨平台对路径字符的处理是避免不了的, 所以有下面几个问题:

a、目录分隔符怎样处理呢?

b、编码怎样统一?

c、路径的分割怎样处理?

filesystem path出现之前, 工作实践为:

windows/linux统一内部使用目录分隔符/;

windows/linux交互存储使用UTF-8编码;

windows下使用UNICODE API处理,存储交互转化成UTF-8, 避免使用ANSI;

这样基本就解决了跨平台问题, 那么filesystem path是怎样处理的呢?

2. 标准文档

标准文件搬运, 方便阅读记录std::filesystem::path - cppreference.com

路径名拥有下列语法:

  1. 根名(可选):标识具有多根的文件系统(如 "C:" 或 "//myserver")的根。有歧义的情况下,将组成合法 根名 的最长序列当做 根名。标准库可以在 OS API 所了解的 根名 外,定义额外的 根名
  2. 根目录(可选):目录分隔符,若存在,则标记此路径为绝对。若缺失(且异于根名的首元素是文件名),则路径为相对且要求另一路径作为解决此文件名的起始位置。
  3. 零或多个下列者:
  4. 文件名:不由目录分隔符或偏好目录分隔符组成的字符序列(操作系统或文件系统可能加上附加限制)。此名称可能标识一个文件、硬链接或目录。辨别两种特殊的 文件名
  5. :由单个点字符. 构成的文件名是指代当前目录的目录名
  6. 点点:由两个点字符 .. 构成的文件名是指代父目录的目录名。
  7. 目录分隔符:正斜杠字符 / 或作为 path::preferred_separator 提供的另一种字符。若重复此字符,则它被处理成单个目录分隔符:/usr///////lib 与 /usr/lib 相同。

path能以下列算法正常化

  1. 若路径为空,则停止(空路径的正常形式是空路径)。
  2. 替换每个 目录分隔符(可以由多重斜杠组成)为单个 path::preferred_separator
  3. 替换 根名 中的每个斜杠字符为 path::preferred_separator
  4. 移除每个 和立即后随的 目录分隔符
  5. 移除每个立即后随 目录分隔符 和一个 点点 的非 点点 文件名,还有立即跟随的 目录分隔符
  6. 若存在 根目录,则移除立即跟随它们的所有 点点 及任何 目录分隔符
  7. 若最终文件名是 点点,则移除任何尾随的 目录分隔符
  8. 若路径为空,则添加一个 (./ 的正常形式是 .)。

路径可由 begin() 与 end() 函数返回的迭代器逐元素进行遍历,这会以通用格式查看路径,并在根名、根目录及后继文件名元素上迭代(跳过目录分隔符,除了标识根目录者)。若路径中的最后元素是目录分隔符,则最后的迭代器将解引用为空元素。

调用任何的 path 非 const 成员函数会令所有引用该对象元素的迭代器失效。

若 OS 使用异于上述可移植通用语法的原生语法,则库函数被定义为接受“受检测格式”,以接受两种格式的路径名:当且仅当受检测格式匹配通用格式,但不为操作系统作为原生路径接受,才采用受检测格式参数。原生格式在目录路径名和文件路径名有别的 OS 上,若通用路径名以目录分隔符终止,则将它当做目录路径,否则当做常规文件。

任何情况下,path 类表现如同它以原生格式存储路径名,并自动于所需场合转换它为通用格式(每个成员函数都指定它转译的路径格式)。

POSIX 系统上,通用格式就是原生格式,并且没有必要区别或转换它们。

路径可隐式转换自及转换成 std::basic_string,这使得在文件 API 上使用它们可行。

流运算符使用 std::quoted 以使空白不会导致其后通过流输入运算符的读取发生截断。

分解成员函数(如 extension)返回 filesystem::path 对象而不是如其他 API 那样返回字符串对象。

成员类型与常量

类型

定义

value_type

文件系统原生编码所用的字符类型:

POSIX 上为 char,Windows 上为 wchar_t

string_type

std::basic_string<value_type>

const_iterator

value_typepath 的常量老式输入迭代器 (LegacyInputIterator) ,符合老式双向迭代器 (LegacyBidirectionalIterator) 的所有要求,但对于两个相等且可解引用的 const_iterator 类型的迭代器 ab,不要求 *a 与 b 指代同一对象。const_iterator 是否实际为[老式双向迭代器* (LegacyBidirectionalIterator) ](https://zh.cppreference.com/w/cpp/named_req/BidirectionalIterator)是未指定的。

iterator

const_iterator 的别名

format

确定如何解读路径名的字符串表示亦定义下列枚举项:

常量解释

native_format原生路径格式

generic_format通用路径格式

auto_format实现定义格式,如果可能就自动检测 (枚举)

成员常量

constexpr

value_type

preferred_separator

[static]

在可移植的 / 之外可用的另一种目录分隔符。

Windows 上它是反斜杠字符 \。

POSIX 上它是与可移植分隔符相同的斜杠 /

(公开静态成员常量)



成员函数

(构造函数)

构造一个 path (公开成员函数)

(析构函数)

销毁 path 对象 (公开成员函数)

operator=

赋值另一个路径 (公开成员函数)

assign

赋值内容 (公开成员函数)

连接


append

operator/=

以目录分隔符向路径添加元素 (公开成员函数)

concat

operator+=

连接两个路径而不加入目录分隔符 (公开成员函数)

修改器


clear

擦除内容 (公开成员函数)

make_preferred

转换目录分隔符为首选目录分隔符 (公开成员函数)

remove_filename

移除文件名路径组分 (公开成员函数)

replace_filename

以另一路径替换最末的路径组分 (公开成员函数)

replace_extension

替换扩展名 (公开成员函数)

swap

交换两个路径 (公开成员函数)

格式观察器


c_str

native

operator

string_type

返回路径的原生版本 (公开成员函数)

string

wstring

u8string

u16string

u32string

返回转换到字符串的原生路径名格式的路径 (公开成员函数)

generic_string

generic_wstring

generic_u8string

generic_u16string

generic_u32string

返回转换到字符串的通用路径名格式 (公开成员函数)

比较


compare

以字典序比较两个路径的词法表示 (公开成员函数)

生成


lexically_normal

lexically_relative

lexically_proximate

转换路径到正常形式 转换路径到相对形式 转换路径到近似形式 (公开成员函数)

分解


root_name

若存在则返回路径的根名 (公开成员函数)

root_directory

若存在则返回路径的根目录 (公开成员函数)

root_path

若存在则返回路径的根路径 (公开成员函数)

relative_path

返回相对根路径的路径 (公开成员函数)

parent_path

返回父路径的路径 (公开成员函数)

filename

返回文件名路径组分 (公开成员函数)

stem

返回主干路径组分(不带扩展名的文件名) (公开成员函数)

extension

返回文件扩展名路径组分 (公开成员函数)

查询


empty

检查路径是否为空 (公开成员函数)

has_root_path

has_root_name

has_root_directory

has_relative_path

has_parent_path

has_filename

has_stem

has_extension

检查对应路径元素是否非空 (公开成员函数)

is_absoluteis_relative

检查 root_path() 是否唯一标识文件系统位置 (公开成员函数)

迭代器


beginend

将路径作为元素序列访问的迭代器 (公开成员函数)

非成员函数



swap(std::filesystem::path)

交换两个路径 (函数)

hash_value

计算路径对象的散列值 (函数)

operator==

operator!=(C++20 前)

operator<(C++20 前)

operator<=(C++20 前)

operator>(C++20 前)

operator>=(C++20 前)

operator<=>(C++20)

以字典序比较两个路径 (函数)

operator/

用目录分隔符连接两个路径 (函数)

operator<>

进行路径上的流输入及输出 (函数)

u8path(C++17)

(C++20 中弃用)

从 UTF-8 编码的源创建 path (函数)

辅助类

在命名空间 std 定义


std::hash(C++17)

std::filesystem::path 的散列支持 (类模板特化)





std::filesystem::path构造函数

path() noexcept;

(1)

(C++17 起)

path( const path& p );

(2)

(C++17 起)

path( path&& p ) noexcept;

(3)

(C++17 起)

path( string_type&& source, format fmt = auto_format );

(4)

(C++17 起)

template< class Source > path( const Source& source, format fmt = auto_format );

(5)

(C++17 起)

template< class InputIt > path( InputIt first, InputIt last, format fmt = auto_format );

(6)

(C++17 起)

template< class Source > path( const Source& source, const std::locale& loc, format fmt = auto_format );

(7)

(C++17 起)

template< class InputIt > path( InputIt first, InputIt last, const std::locale& loc, format fmt = auto_format );

(8)

(C++17 起)




构造新的 path 对象。

1) 构造空路径。

2) 复制构造函数。构造一个路径,其原生与通用格式的路径名均与 p 相同

3) 移动构造函数。构造一个路径,其原生与通用格式的路径名均与 p 相同,p 留在合法而未指定的状态。

4-6) 从 source (4,5) 提供的字符序列构造路径(按 fmt 指定的格式转译),源可以是一个指向空终值字符/宽字符序列的指针或输入迭代器,std::basic_string 或 std::basic_string_view,或作为一对输入迭代器 [first, last) 提供 (6)。允许任何字符类型 char、char8_t (C++20 起)、char16_t、char32_t、wchar_t,而且原生字符集的转换方法依赖于 source 所用的字符类型

若源字符类型是 char8_t,则使用从 UTF-8 到原生文件系统编码的转换。

(C++20 起)



7,8) 从 source (7) 提供的从字符序列构造路径(按 fmt 指定的格式转译),源可以是指向空终止字符序列的指针或输入迭代器,std::string,std::basic_string_view,或由一对输入迭代器 [first, last) (8) 所代表。仅允许的字符类型是 char。用 loc 进行字符编码转换。若 value_type 是 wchar_t,则使用 loc 的 std::codecvt<wchar_t, char, std::mbstate_t> 平面从宽字符转换。否则,首先用 std::codecvt<wchar_t, char, std::mbstate_t> 平面转换到宽字符,再用 loc 的 std::codecvt<wchar_t,value_type> 平面转换到文件系统原生字符类型。

仅若 Sourcepath 不是同一类型,而且:

  • Source 是 std::basic_string 或 std::basic_string_view 的特化,或
  • std::iterator_traits[std::decay_t](http://zh.cppreference.com/w/cpp/types/decay)<Source>::value_type 合法并代表可能有 const 限定的编码字符类型(char、char8_t、 (C++20 起)char16_t、char32_t 或 wchar_t)

(5) 与 (7) 才参与重载决议。

参数

p

要复制的路径

source

std::basic_string,std::basic_string_view,指向空终止字符串的指针,或拥有字符值类型并指向空终止字符序列的的输入迭代器(对于重载 (7) 字符类型必须是 char)

first, last

一对指定字符序列的老式输入迭代器 (LegacyInputIterator)

fmt

path::format 类型的枚举项,指定路径名格式如何转译

loc

定义编码转换所用的本地环境

类型要求


-InputIt 必须满足老式输入迭代器 (LegacyInputIterator)


-InputIt 的值类型

必须是字符类型

char、

char8_t (C++20 起)、

wchar_t、

char16_t

及 char32_t 之一,

以使用重载 (6)。


-InputIt 的值类型必须是 char,以使用 (8)。


异常

2,4-8) 可能会抛出由实现定义的异常。

** 注解**

关于从 Unicode 字符串生成可移植路径名,见 u8path

(C++20 前)

源为 char8_t 的序列时,path 构造函数支持从 UTF-8 字符串创建。

(C++20 起)

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: