C++ STL之filesystem文件系统库详解

filesystem库——C++文件操作(基本语法,常用函数封装) 【代码】filesystem库——C++文件操作(输出文件名,判断文件是否为空、) 阅读详情

C++ STL之filesystem文件系统库详解

一、从 Boost 到标准库:filesystem 的前世今生

C++17 之前,跨平台文件操作是噩梦。Windows 用 GetFileAttributesW、Linux 用 stat、Mac 用 NSFileManager——每套 API 各有千秋,但无一适用于跨平台场景。多数项目转向 boost::filesystem,但 Boost 毕竟不是标准,团队引入需额外依赖、配置构建链。

C++17 正式将 std::filesystem 纳入标准库,头文件 <filesystem>,命名空间 std::filesystem。它统一了路径分隔符(/ vs \)、文件属性提取、目录遍历、磁盘容量查询等操作,且无第三方依赖。

#include <filesystem>
namespace fs = std::filesystem;

int main() {
    fs::path p = "/home/user/file.txt";
    bool exists = fs::exists(p);
    return 0;
}

二、path 类与正规化

path 是 filesystem 库的核心类型,负责跨平台路径表示。它不检查路径是否真实存在,只做字符串操作。

常见操作

操作说明
p.root_name()返回根名(Windows 的 C:)
p.root_directory()返回根目录(/ 或 \)
p.parent_path()父路径
p.filename()文件名(含后缀)
p.stem()不带后缀的文件名
p.extension()后缀(含 .)

正规化:lexically_normal

移除路径中的 .、.. 和多余分隔符,返回逻辑上"干净"的路径。

fs::path p = "a/./b/../c/file.txt";
fs::path norm = p.lexically_normal();
// 结果: "a/c/file.txt"

如果路径中有 . 表示当前目录,.. 表示上一级父目录,lexically_normal 会将它们约简。注意这是纯字符串操作,不会访问磁盘。

make_preferred

将路径分隔符转为当前平台惯用格式:Windows 转 \,POSIX 转 /。

fs::path p = "a/b/c";
p.make_preferred(); // Windows: a\b\c,  Linux: a/b/c

原始路径: a/./b/../c/file.txt

lexically_normal

去除 .

回退 ..

正规化结果: a/c/file.txt

make_preferred

Windows: a\\b\\c

POSIX: a/b/c

三、directory_entry 的缓存机制

directory_entry 封装了文件系统的一条记录,包括路径和属性。它的核心设计是缓存:首次访问文件属性后,结果会被内部缓存,后续访问不再触发系统调用。

fs::directory_entry entry("/home/user/file.txt");
auto size1 = entry.file_size();  // 触发 stat
auto size2 = entry.file_size();  // 返回缓存,无系统调用
entry.refresh();                  // 强制刷新缓存
auto size3 = entry.file_size();  // 重新 stat

这在遍历大量文件时能显著减少 I/O:一次 directory_iterator 操作自动填充 directory_entry,后续取 file_size、last_write_time、file_type 等都走缓存。

四、目录遍历:directory_iterator 与 recursive_directory_iterator

两套 API 对应两种遍历范围:

特性directory_iteratorrecursive_directory_iterator
遍历深度仅当前目录递归子目录
是否含 . ..否否
排序未定义未定义
跳过子目录不适用disable_recursion_pending()
void list_all(const fs::path& dir) {
    fs::directory_iterator end;
    for (auto it = fs::directory_iterator(dir); it != end; ++it) {
        // 只有第一层
    }
    for (auto it = fs::recursive_directory_iterator(dir); it != fs::recursive_directory_iterator(); ++it) {
        // 递归全部
        if (it->is_directory() && skip(*it))
            it.disable_recursion_pending();
    }
}

是

否

是

是

否

否

开始遍历

选择迭代器类型

directory_iterator?

recursive_directory_iterator?

打开当前目录

读取下一个条目

还有条目?

返回 directory_entry

结束

打开当前目录

读取下一个条目

还有条目?

是目录且
未禁用递归?

递归进入子目录

返回 directory_entry

两种迭代器返回的都是 directory_entry,可直接调用 is_regular_file()、file_size()、path() 等。

五、space_info:磁盘容量查询

std::filesystem::space() 返回 space_info 结构体:

struct space_info {
    uintmax_t capacity;   // 总容量
    uintmax_t free;       // 剩余容量(给调用者的配额)
    uintmax_t available;  // 可用容量(含非特权用户的配额限制)
};
fs::space_info si = fs::space("/");
std::cout << "总容量: " << si.capacity / 1e9 << " GB\n";
std::cout << "剩余: "   << si.free / 1e9 << " GB\n";
std::cout << "可用: "   << si.available / 1e9 << " GB\n";

free 与 available 的区别:POSIX 系统上,free 是文件系统层未使用的块数,available 还要扣除 root 预留块。非 root 用户看到 available 小于 free。

六、copy 与 copy_options

fs::copy 复制文件或目录,搭配 copy_options 控制行为:

选项效果
none默认,已存在时报错
skip_existing跳过已有文件,不报错
overwrite_existing覆盖已有文件
update_existing仅目标更旧时才覆盖
recursive递归复制子目录
directories_only仅复制目录结构
create_symlinks复制为符号链接
void backup(const fs::path& src, const fs::path& dst) {
    fs::copy_options opts =
        fs::copy_options::recursive |
        fs::copy_options::overwrite_existing |
        fs::copy_options::update_existing;
    fs::copy(src, dst, opts);
}

注意 fs::copy 在目录上默认不递归,必须显式加 copy_options::recursive 才能复制子目录。

七、面试题精选

1. lexically_normal 会访问磁盘吗?

不会。它是纯字符串操作,只处理 ./ 和 ../ 路径分量,不检查文件是否存在。如果需要解析符号链接或相对路径的绝对化,用 canonical 或 weakly_canonical(会访问磁盘)。

2. directory_iterator 返回的条目有顺序保证吗?

没有。遍历顺序由底层文件系统决定,不可预测。若需有序遍历,须手动收集到 std::vector 再排序。

3. directory_entry 缓存什么时间生效?如何刷新?

首次调用 file_size()、last_write_time()、status() 等触发系统调用后缓存结果。文件在外部被修改时缓存变脏,需调用 refresh() 刷新。缓存不自动感知外部变更。

4. copy_options::recursive 和 copy_options::directories_only 可以同时使用吗?

可以。组合后会在目标递归创建完整的目录结构,但不复制任何文件。常用于备份前建好骨架。

5. space_info::free 和 space_info::available 实际有什么区别?

free 是文件系统层空闲块,available 还要排除特权预留(ext4 默认 5% 给 root)。用户态程序应优先读 available,否则写的字节可能被 ENOSPC 拒绝。

6. path 的 operator/= 做了什么?与字符串拼接有何不同?

operator/= 会自动插入平台分隔符(/ 或 \),且不会重复。字符串拼接可能导致 a//b 或 a\b 混用。优先用 operator/= 而不是 fs::path(a.string() + "/" + b.string())。

7. recursive_directory_iterator 如何跳过某个子目录?

调用 disable_recursion_pending(),析构后迭代器会跳过当前条目(须是目录)下的所有内容。

for (auto it = fs::recursive_directory_iterator("."); it != fs::recursive_directory_iterator(); ++it) {
    if (it->path().filename() == ".git")
        it.disable_recursion_pending();
    else
        process(*it);
}

8. 如何判断一个 path 是绝对路径?

  • p.is_absolute():检查是否绝对路径(POSIX 以 / 开头,Windows 含根名+根目录)
  • p.is_relative():上述取反

Windows 上 C:/foo 是绝对路径,. 是相对路径,/foo 仅含根目录但无根名,按 Windows 规则也是相对路径。

【C++】filesystem filesystem>是引入的标准库,主要用于处理文件系统的目录和文件操作,接下来总结该库的日常使用。 阅读详情

相关推荐

C++精灵库入门:简化游戏开发与现代C++实践

C++作为系统级编程语言,其内存管理和模板等高级特性常给初学者带来学习障碍。现代C++通过RAII机制和智能指针等特性简化资源管理,而游戏开发领域常用的精灵(Sprite)概念则提供了直观的编程切入点。精灵库(sprites.h)这类工具封装了游戏开发常见操作,既降低了入门门槛,又融合了C++17现代特性。通过可视化游戏元素的操作,开发者能自然掌握智能指针、lambda表达式等核心概念,同时学习渲染优化、着色器编程等图形学技术。这种结合具体应用场景的教学方式,特别适合解决C++初学者的'指针恐惧症'问题。

weixin_30345577的博客 289

boost I 操作系统相关的库(二)- filesystem系统

目录 一、path 1.path构造 2.追加路径 3.获取完整绝对路径 4.文件名可移植性判断 5.路径分析 6.路径修改 7.异常处理 二、文件 1.文件状态类file_status 2.文件属性 3.文件操作 三、目录迭代 1.单层遍历 2.递归实现深度遍历 3.recursive_directory_iterator 四、文件流操作 filesystem库是一个可移植的文件系统操作库,已被收入 C ++17 标准。它在底层做了大量的工作,使用POS...

该用户还没想到好的昵称的博客 2714

[c++17标准库特性之新增STL特性] --- std::filesystem

C++17 标准库中的文件系统库提供了一些函数和类来处理文件和目录。

M2嵌入式 1256

快速了解C++17 std:: filesystem的原理和使用

第一章: 基本介绍 `filesystem` 库是 C++17 中引入的一个重要特性,它提供了一系列用于文件系统操作的功能。这个库包含在 `` 头文件中,并且定义在 `std::filesystem` 命名空间内。 `std::filesystem` 库提供了许多功能,包括但不限于: 1. **路径操作** (`std::filesystem::path`): 用于处理文件和目录路径的类。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 3662

filesystem

File system.PDF

三维视觉智能焊接系统:免示教技术的工业应用实践

本文深入探讨了三维视觉智能焊接系统中免示教技术的工业应用实践。该系统通过三维视觉相机实时扫描工件,自动识别焊缝并生成轨迹,将产线换型时间从数小时缩短至几分钟,显著提升了生产柔性。文章详细解析了其核心硬件、算法及工厂部署流程,并展望了与数字孪生、工艺智能化融合的未来趋势。

weixin_29091105的博客 432

c++标准库学习-filesystem文件系统库(1)-path对象

c++标准库文件系统库

qq_52095705的博客 4667

Visual Studio Installer下载失败的5种修复方法(含DNS修改/补丁安装)

本文针对Visual Studio Installer下载安装文件失败的问题,提供了从网络层到系统层的深度排查与修复指南。详细介绍了DNS修改、代理配置、防火墙设置、系统服务检查等5种核心修复方法,并包含离线安装与手动补丁等替代方案,帮助开发者彻底解决安装难题。

sprite的博客 1617

C++标准模板(STL)- 文件系统库

若层级文件系统不能为实现所访问,或若它不提供必要的兼容性,则文件系统库设施可能不可用。若底层文件系统不支持,则一些特性可能不可用(例如 FAT 文件系统缺少符号链接并禁止多重硬链接)。这些情况下必须报告错误。 若对此库的函数的调用引入文件系统竞争,即多个线程、进程或计算机交错地访问并修改文件系统中的同一对象,则行为未定义。

qq_40788199的博客 1019

使用网分对晶体ESR/L1/C1/C0进行测量计算

Use R&amp;S Vector Network Analyzer test XTAL ESR/L1/C1/C0 測量方法:使用儀器的Port1端口,測量XTAL的S11,通過諧振的參數計算出ESR/L1/C1/C0的值。 實際晶體的等效模型:通常方便晶體分析,使用下圖(b)的等效模型,但實際測量發現晶體存在多個串聯諧振點,實際等效模型更接近(c)。 儀器測量到的S11,其中M...

qq_39138630的博客 2083

多IMU车载GNSS/INS数据集及介绍

文章目录前言非常棒的GINS数据集采集轨迹采集时间MEMS IMU详细信息IMU测量值方程及相关误差建模参考噪声参数安装参数文件格式描述 前言 “本文作者感谢武汉大学多源智能导航实验室和牛小骥教授提供了本文所需的GNSS/INS数据集。” 本博文介绍数据集链接为多IMU车载GNSS、INS数据集,欢迎大家下载,由于是开源数据集,因此下载不需要积分 非常棒的GINS数据集 这是一套非常好的用于GNSS/INS组合导航应用的车载数据集,本数据集采集于湖北省武汉市一处工业园区,为开阔天空场景,GNSS R

十八与她的博客 6439

C++标准模板(STL)- 文件系统库 - 表示一个路径 (std::filesystem::path)

类型 path 的对象表示文件系统上的路径。只有路径的语法外观得到处理:路径名可能表示不存在的路径,或甚至不允许存在于当前文件系统或操作系统的路径。

qq_40788199的博客 1442

差分运放实战:如何快速计算带直流偏置的电路(附详细推导步骤)

本文详细解析了差分运放电路在带直流偏置设计中的核心计算方法和实战技巧。通过可视化参数关系和分步拆解,帮助工程师快速掌握电路设计精髓,包括虚短虚断原理、偏置电压计算及非理想因素处理,提升信号调理和传感器接口设计的效率与精度。

o4p5q6r7s的博客 409

C++ STL CookBook

我们下面来聊一聊C++17新加入的filesystem。STL 文件系统库的目的是跨平台规范化文件系统操作。文件系统库旨在规范化操作,弥合 POSIX/Unix、Windows 和其他文件系统之间的不规则性。文件系统库是从相应的 Boost 库中采用的,并通过 C++17 合并到 STL 中。在撰写本文时,它在某些系统上的实现仍然存在差距,但本章中的配方已经在 Linux、Windows 和 macOS 文件系统上进行了测试,并分别使用 GCC、MSVC 和 Clang 编译器的最新版本进行编译。该库使用。

charlie114514191的博客 681

MPC模型预测控制实战:从理论到代码实现(Python示例)

本文详细介绍了MPC模型预测控制的实战应用,从理论到Python代码实现。通过构建系统模型、预测方程、优化问题及约束处理,展示了如何实现一个完整的MPC控制器。文章还提供了水箱液位控制的应用案例,帮助读者掌握MPC在工业控制中的实际应用。

weixin_42653691的博客 460

【智能制造】- APS系列|05 APS 排产的五大底层算法逻辑

很多人误以为APS只是给生产工单排先后顺序,实则整套系统依托成熟算法体系,完成多维度约束下的最优生产决策在制造业数字化排产普及的当下,依旧有不少制造管理者对APS存在认知误区,将其等同于简易工单排序工具。事实上,专业级高级计划与排程系统,早已脱离单纯按时间排序的基础功能,而是依托一整套成熟完善的底层算法逻辑,整合现场各类生产限制条件,在海量变量中自动推演、筛选、输出最贴合企业经营目标的生产方案。

qq_40821260的博客 433

C++ STL与Boost库选型指南:资深工程师的实战经验总结

在C++开发中,标准模板库(STL)和Boost库是两大核心工具集,理解它们的定位差异对项目技术选型至关重要。STL作为C++标准的一部分,提供了容器、算法和迭代器等基础组件,具有极佳的可移植性和性能,是构建可靠软件的首选。其设计遵循最小化和正交化原则,确保了代码的稳定性和跨平台一致性。相比之下,Boost库则扮演着前沿试验场的角色,提供了智能指针、文件系统操作和异步I/O等扩展功能,许多特性后来被纳入C++标准。从工程实践角度看,合理选择工具能显著提升开发效率和代码质量。例如,在内存管理场景中,C++11

weixin_33910385的博客 374

031、速度前馈与加速度前馈

摘要: 本文通过追剪机调试案例,阐述了速度前馈和加速度前馈在运动控制中的关键作用。前馈不是高级技巧,而是解决动态响应问题的必要手段:速度前馈通过预测速度变化提前补偿,加速度前馈则针对惯量变化提供力矩补偿。实现时需注意信号平滑处理,避免噪声放大。前馈与PID分工明确,前馈承担主要动态响应,PID处理残余误差。调试应先调前馈再微调PID,前馈增益需计算而非仅凭参数调整,并允许适当残余误差。前馈作为开环补偿不会影响系统稳定性,但需配合平滑的指令生成器使用。(149字)

m0_50546716的博客 284

CPP-17-STL-cookbook文件系统操作:跨平台文件处理最佳实践

CPP-17-STL-cookbook是一本实用的C++17标准库指南,其中文件系统操作章节详细介绍了如何使用`std::filesystem`库进行跨平台文件处理。本文将分享C++17文件系统操作的核心功能与最佳实践,帮助开发者轻松处理Windows、Linux和MacOS等不同操作系统的文件系统差异。 ## 为什么选择std::filesystem? C++17引入的`std::files

gitblog_00545的博客 1041

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

c++17--filesystem

c++17的新特性。

m0_60274660的博客 1328

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

标准库标头 <filesystem> (C++17)学习

​此头文件是文件系统支持库的一部分。本篇介绍filesystem命名空间的一些函数。 ​

chenyijun的专栏 993

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C++17标准库冷知识:filesystem目录迭代的3种非常规用法,你知道吗?

掌握C++17 filesystem的目录迭代技巧,轻松应对复杂文件遍历场景。介绍递归遍历、符号链接处理与过滤器应用三种非常规用法,提升效率与代码健壮性,值得收藏。

InstrWander的博客 955

Apache Arrow C++ 文件系统(Filesystem)API 完全指南:统一抽象、工厂注册与本地/S3/HDFS/GCS/Azure 实现详解

Apache Arrow 的 C++ 文件系统模块(`arrow::fs`)为本地磁盘、Amazon S3、Hadoop HDFS、Google Cloud Storage(GCS)与 Azure Blob/Data Lake Storage 等异构存储后端提供了**同一套统一抽象**,让上层代码(如 Arrow Dataset、Parquet/Feather 读写、IPC 流)无需关心底层存储差

gitblog_00377的博客 150

C++ STL/BOOST混搭遇到 filesystem fs::directory_iterator的一个滑稽的错误

通过输出结果可知,默认情况std::distance()不会去操作迭代器beginIter的,beginIter在原位,但是遇到boost的filesystem::directory_iterator迭代器(不确定是否全boost如此),他把我迭代器给“用掉”了,想想也可以理解,迭代器不是平铺的数据,想得到俩迭代器的“距离”,势必做了个iter++操作。最开始没问题,后来说加个进度条,统计一下所有文件数量,用了std::distance,但是理论上你可以留个备份,然后给我恢复,不动我的输入才对。

huqinwei的专栏 820

C++20 STL 秘籍(五)

STL 库的目的是在各个平台上标准化文件系统操作。库旨在标准化操作,弥合 POSIX/Unix、Windows 和其他文件系统之间的不规则性。库是从相应的Boost库中采纳的,并在 C++17 中纳入了 STL。在撰写本文时,一些系统上其实现仍存在空白,但本章中的菜谱已在 Linux、Windows 和 macOS 文件系统上进行了测试,并分别使用最新的 GCC、MSVC 和 Clang 编译器编译。该库使用头文件,并且命名空间通常被别名为: 类是库的核心。它为不同的环境提供了标准化的文件名和目录路径表示。

龙哥盟 549

C++17 STL实战指南:从容器算法到并行编程的现代C++开发

标准模板库(STL)是C++编程的核心组件,它通过泛型编程思想将数据结构与算法分离,提供了容器、迭代器和算法三大支柱。其设计原理基于模板元编程,实现了类型安全的代码复用,技术价值在于显著提升开发效率、代码可读性和运行时性能。在工程实践中,STL广泛应用于数据处理、文本解析、资源管理等场景,而C++17引入的并行算法和结构化绑定等特性进一步扩展了其能力边界。本文聚焦于C++17 STL的实战应用,深入解析std::vector、std::map等容器的选择策略,以及std::remove_if、std::pa

weixin_29698641的博客 278
上一篇: C++ STL 之 string_view 详解
下一篇: tech-batch 写审分离:AI 批量写技术博文的质量控制
Ricky_Theseus
博客等级 码龄3年 126粉丝 158原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ricky_Theseus

感谢大家,祝您生活愉快

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值