当前位置: 首页 > news >正文

C++中如何使用文件系统路径

文章目录

      • 使用 `<filesystem>`
      • 使用 Boost FileSystem
      • 注意事项
    • 案例展示
      • 示例代码
      • 解释
      • 增强后的示例代码
      • 功能增强说明
      • 使用示例
      • 新增功能后的代码
      • 新功能说明
      • 使用示例

在 C++ 中处理文件系统路径通常涉及到创建、解析、标准化路径等操作。C++ 标准库直到 C++17 才引入了 <filesystem> 库,这使得跨平台的文件系统操作变得更为简单和一致。在此之前,人们可能会依赖于第三方库(如 Boost FileSystem)或操作系统特定的 API 来实现这些功能。

使用 <filesystem>

如果你的编译器支持 C++17 或更高版本,你可以直接使用 <filesystem> 头文件。以下是一些基本的用法示例:

#include <iostream>
#include <filesystem>namespace fs = std::filesystem;int main() {// 创建路径对象fs::path p1("/home/user/documents");fs::path p2{ "c:\\temp\\example.txt" }; // 使用大括号初始化可以避免转义字符// 检查路径是否存在if (fs::exists(p1)) {std::cout << p1 << " 存在。\n";} else {std::cout << p1 << " 不存在。\n";}// 输出路径的类型if (fs::is_directory(p1)) {std::cout << p1 << " 是目录。\n";}if (fs::is_regular_file(p2)) {std::cout << p2 << " 是普通文件。\n";}// 创建目录fs::create_directories("/home/user/newfolder/subfolder");// 删除文件或空目录if (fs::exists(p2)) {fs::remove(p2);}// 更多操作...
}

使用 Boost FileSystem

如果你使用的是旧版 C++ 编译器,或者想要更丰富的特性,Boost 提供了一个叫做 Boost.FileSystem 的库。使用方法与 <filesystem> 类似,但是需要包含不同的头文件,并且命名空间也不同。

#include <iostream>
#include <boost/filesystem.hpp>namespace fs = boost::filesystem;int main() {fs::path p1("/home/user/documents");fs::path p2{ "c:\\temp\\example.txt" };if (fs::exists(p1)) {std::cout << p1 << " 存在。\n";} else {std::cout << p1 << " 不存在。\n";}if (fs::is_directory(p1)) {std::cout << p1 << " 是目录。\n";}if (fs::is_regular_file(p2)) {std::cout << p2 << " 是普通文件。\n";}// 创建目录fs::create_directories("/home/user/newfolder/subfolder");// 删除文件或空目录if (fs::exists(p2)) {fs::remove(p2);}// 更多操作...
}

注意事项

  • 在使用 <filesystem>Boost.Filesystem 之前,请确保你的项目配置正确,并且链接了相应的库。
  • 处理路径时,要考虑到不同操作系统之间的差异,比如路径分隔符(Windows 上是 \,Unix-like 系统上是 /)。
  • 当创建路径对象时,可以使用 {} 初始化来避免处理转义序列的问题。
  • 进行文件系统操作时,确保你有足够的权限来执行这些操作,否则会抛出异常或返回错误代码。

通过上述方法,你可以方便地进行路径操作、文件读写以及目录管理等任务。

案例展示

下面我将提供一个具体的例子来展示如何使用 <filesystem> 库来完成一些常见的文件系统任务,如列出目录中的所有文件、创建目录结构、删除文件等。

假设我们需要编写一个程序,该程序能够列出指定目录下的所有文件及其子目录中的文件,并提供选项来创建新的目录结构或删除某些文件。

示例代码

#include <iostream>
#include <string>
#include <filesystem>
#include <cassert>namespace fs = std::filesystem;void listFiles(const fs::path& directoryPath) {try {for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {if (entry.is_regular_file()) {std::cout << entry.path() << '\n';}}} catch (const fs::filesystem_error& ex) {std::cerr << "Error: " << ex.what() << '\n';}
}void createDirectoryStructure(const fs::path& path) {try {if (!fs::exists(path)) {fs::create_directories(path);std::cout << "创建目录: " << path << '\n';} else {std::cout << "目录已存在: " << path << '\n';}} catch (const fs::filesystem_error& ex) {std::cerr << "Error creating directory: " << ex.what() << '\n';}
}void deleteFile(const fs::path& path) {try {if (fs::exists(path)) {fs::remove(path);std::cout << "删除文件: " << path << '\n';} else {std::cout << "文件不存在: " << path << '\n';}} catch (const fs::filesystem_error& ex) {std::cerr << "Error removing file: " << ex.what() << '\n';}
}int main() {// 目标目录fs::path targetDirectory = "/path/to/directory";// 列出目录中的所有文件std::cout << "List of files in the directory:\n";listFiles(targetDirectory);// 创建目录结构fs::path newDirectory = "/path/to/new/directory/structure";createDirectoryStructure(newDirectory);// 删除文件fs::path filePathToDelete = "/path/to/file/to/delete.txt";deleteFile(filePathToDelete);return 0;
}

解释

  1. listFiles 函数使用 fs::recursive_directory_iterator 遍历目录及其子目录中的所有条目,并打印出所有的文件路径。
  2. createDirectoryStructure 函数检查给定的路径是否存在,如果不存在则创建它。
  3. deleteFile 函数尝试删除指定的文件,如果文件存在的话。
  4. main 函数演示了如何调用这些函数来完成任务。

请根据实际需求修改 targetDirectorynewDirectoryfilePathToDelete 变量中的路径值。注意,在运行此程序之前,你需要确保路径有效,并且程序具有相应的权限来进行文件系统操作。此外,这个程序假设你正在使用支持 C++17 的编译器。如果不支持,则可能需要使用 Boost 或其他方法。

接下来,让我们继续扩展上面的例子,并添加一些额外的功能,例如允许用户从命令行输入参数,以便更灵活地控制程序的行为。我们还将添加一些额外的错误处理,以提高程序的健壮性。

增强后的示例代码

#include <iostream>
#include <string>
#include <filesystem>
#include <cassert>namespace fs = std::filesystem;void listFiles(const fs::path& directoryPath) {try {for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {if (entry.is_regular_file()) {std::cout << entry.path() << '\n';}}} catch (const fs::filesystem_error& ex) {std::cerr << "Error listing files: " << ex.what() << '\n';}
}void createDirectoryStructure(const fs::path& path) {try {if (!fs::exists(path)) {fs::create_directories(path);std::cout << "Created directory: " << path << '\n';} else {std::cout << "Directory already exists: " << path << '\n';}} catch (const fs::filesystem_error& ex) {std::cerr << "Error creating directory: " << ex.what() << '\n';}
}void deleteFile(const fs::path& path) {try {if (fs::exists(path)) {fs::remove(path);std::cout << "Deleted file: " << path << '\n';} else {std::cout << "File does not exist: " << path << '\n';}} catch (const fs::filesystem_error& ex) {std::cerr << "Error removing file: " << ex.what() << '\n';}
}int main(int argc, char* argv[]) {if (argc < 2) {std::cerr << "Usage: " << argv[0] << " [list|create|delete] path\n";return EXIT_FAILURE;}const std::string command = argv[1];fs::path path;if (argc < 3) {std::cerr << "Missing path argument.\n";return EXIT_FAILURE;} else {path = argv[2];}if (command == "list") {listFiles(path);} else if (command == "create") {createDirectoryStructure(path);} else if (command == "delete") {deleteFile(path);} else {std::cerr << "Unknown command: " << command << ".\n";return EXIT_FAILURE;}return EXIT_SUCCESS;
}

功能增强说明

  1. 命令行参数

    • 程序现在接受命令行参数,用于指定要执行的操作(list, create, delete)和目标路径。
    • 如果没有提供足够的参数,程序将输出正确的使用方式并退出。
  2. 错误处理

    • 在每个关键操作中都增加了错误捕获逻辑,确保在遇到文件系统错误时能够给出提示信息。
    • 对于未知命令,也会给出提示并退出程序。
  3. 操作选择

    • 用户可以通过命令行参数选择是要列出目录内容 (list)、创建目录 (create) 还是删除文件 (delete)。

使用示例

假设你将上述程序编译为可执行文件 fileops,那么可以这样使用:

  • 列出目录中的文件:./fileops list /path/to/directory
  • 创建目录结构:./fileops create /path/to/new/directory/structure
  • 删除文件:./fileops delete /path/to/file/to/delete.txt

这样的设计使程序更加通用,并且可以根据用户的输入动态地调整其行为。如果你有更多具体的需求或者想要增加其他功能,可以根据这个基础进一步扩展。

我们可以继续扩展之前的示例,使其功能更加完善,并增加一些实用的功能,比如:

  1. 添加一个帮助选项来显示程序的使用方法。
  2. 支持递归删除目录及其内容。
  3. 在删除文件或目录前询问用户确认。
  4. 添加更多的错误处理逻辑,确保程序更加健壮。

新增功能后的代码

#include <iostream>
#include <string>
#include <filesystem>
#include <cassert>namespace fs = std::filesystem;void listFiles(const fs::path& directoryPath) {try {for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {if (entry.is_regular_file()) {std::cout << entry.path() << '\n';}}} catch (const fs::filesystem_error& ex) {std::cerr << "Error listing files: " << ex.what() << '\n';}
}void createDirectoryStructure(const fs::path& path) {try {if (!fs::exists(path)) {fs::create_directories(path);std::cout << "Created directory: " << path << '\n';} else {std::cout << "Directory already exists: " << path << '\n';}} catch (const fs::filesystem_error& ex) {std::cerr << "Error creating directory: " << ex.what() << '\n';}
}void recursiveDelete(const fs::path& path) {try {if (fs::exists(path)) {if (fs::is_directory(path)) {for (auto it = fs::directory_iterator(path); it != fs::directory_iterator(); ++it) {recursiveDelete(it->path());}}fs::remove_all(path);std::cout << "Deleted: " << path << '\n';} else {std::cout << "Path does not exist: " << path << '\n';}} catch (const fs::filesystem_error& ex) {std::cerr << "Error removing directory: " << ex.what() << '\n';}
}bool confirm(const std::string& message) {std::string input;std::cout << message << " (y/n): ";std::cin >> input;return input == "y" || input == "Y";
}int main(int argc, char* argv[]) {if (argc < 2) {std::cerr << "Usage: " << argv[0] << " [list|create|delete] path\n"<< "       " << argv[0] << " help\n";return EXIT_FAILURE;}const std::string command = argv[1];fs::path path;if (command == "help") {std::cout << "Usage: " << argv[0] << " [list|create|delete] path\n"<< "Commands:\n"<< "  list     List all files in the given directory and subdirectories.\n"<< "  create   Create the given directory structure if it does not exist.\n"<< "  delete   Delete the given file or directory recursively after confirmation.\n";return EXIT_SUCCESS;}if (argc < 3) {std::cerr << "Missing path argument.\n";return EXIT_FAILURE;} else {path = argv[2];}if (command == "list") {listFiles(path);} else if (command == "create") {createDirectoryStructure(path);} else if (command == "delete") {if (confirm("Are you sure you want to delete " + path.string())) {recursiveDelete(path);} else {std::cout << "Deletion canceled.\n";}} else {std::cerr << "Unknown command: " << command << ". Use 'help' for usage information.\n";return EXIT_FAILURE;}return EXIT_SUCCESS;
}

新功能说明

  1. 帮助选项

    • 添加了 help 命令来显示程序的使用方法和命令说明。
  2. 递归删除

    • 实现了 recursiveDelete 函数来递归删除目录及其内容。
    • 在删除前会先询问用户是否确认删除。
  3. 确认删除

    • 在删除文件或目录之前,程序会请求用户确认是否确实要删除。

使用示例

假设你已经将上述程序编译为可执行文件 fileops,那么可以这样使用:

  • 显示帮助信息:./fileops help
  • 列出目录中的文件:./fileops list /path/to/directory
  • 创建目录结构:./fileops create /path/to/new/directory/structure
  • 删除文件或目录(需要确认):./fileops delete /path/to/file/or/directory

通过这些增强的功能,程序变得更加用户友好,并且在执行潜在危险操作(如删除)时更加安全。

😍😍 海量H5小游戏、微信小游戏、Web casualgame源码😍😍
😍😍试玩地址: https://www.bojiogame.sg😍😍
😍看上哪一款,需要源码的csdn私信我😍

————————————————

​最后我们放松一下眼睛
在这里插入图片描述


http://www.mrgr.cn/news/58592.html

相关文章:

  • C++ 类与对象(中) 默认成员函数
  • docker部署rustdesk
  • 【机器学习基础】全连接层
  • 端到端自动驾驶模型SparseDrive部署过程
  • 如何对pdf文件进行加密?pdf文件加密全攻略与深度解析(5个方法)
  • [Linux网络编程]04-多进程/多线程并发服务器思路分析及实现(进程,信号,socket,线程...)
  • AcWing 89:a^b ← 快速幂
  • 136.只出现一次的数字
  • 【开源项目】经典开源项目数字孪生工地——开源工程及源码
  • fpga系列 HDL: 竞争和冒险 01
  • 计算机网络:网络层 —— IPv4 协议的表示方法及其编址方法
  • python 线程间通信用什么手段
  • 微软投资比特币:将总资产1%投资于BTC?股东投票决定最终结果!
  • 洛谷 P1060 [NOIP2006 普及组] 开心的金明
  • C++ 移动语义
  • Vue学习记录之二十 postcss自定义插件及Unocss的使用
  • 遇到这3种接口测试问题,其实,你可以这么办~
  • 混个1024勋章
  • 2023年12月中国电子学会青少年软件编程(图形化)等级考试试卷(二级)答案 + 解析
  • CMU生成式人工智能大模型:从入门到放弃(九)
  • CMU生成式人工智能大模型:从入门到放弃(八)
  • 电机的旋转原理和发电原理!
  • 永恒之蓝漏洞利用复现
  • Oracle故障诊断(一线DBA必备技能)之ADRCI(一)
  • 大数据新视界 -- 大数据大厂之大数据与虚拟现实的深度融合之旅
  • Centos如何卸载docker