首页 > 编程语言 >C++ filesystem 库使用

C++ filesystem 库使用

时间:2023-12-25 20:44:45浏览次数:59  
标签:std fs filesystem C++ sandbox 使用 txt path include

一、filesystem 介绍

filesystem 源自boost.filesystem库,在C++17合并进C++标准库中,filesystem中的所有操作是线程不安全的。

二、路径相关操作

在filesystem库中提供path类来对路径进行操作,后续的相关操作,如打开文件、遍历目录、判断文件类型等,都是需要用path作为参数来指定操作具体路径。

2.1 path 初始化
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
 
int main()
{
    fs::path p; //empty path
    fs::path p1 = "/usr/lib/sendmail.cf"; // portable format
    fs::path p2 = p1; // copy construct
    fs::path p3 = std::move(p1); // move construct
    std::cout << "p = " << p << '\n'
              << "p1 = " << p1 << '\n'
              << "p2 = " << p2 << '\n'
              << "p3 = " << p3 << '\n';
}

output

p = ""
p1 = "" //被移动后p1 变成空路径
p2 = "/usr/lib/sendmail.cf"
p3 = "/usr/lib/sendmail.cf"
2.2 path 路径拼接操作

常见操作目录路径+文件名拼接成完成文件路径
path += 和 / 操作

#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main()
{
    fs::path p1 = "/usr/lib/";
    fs::path p2 = "/usr/lib";
    fs::path p3 = p1 / "text.txt";
    fs::path p4 = p2 / "text.txt"; //会添加反斜杠

    p1 += "text.txt";
    p2 += "text.txt"; //不会添加反斜杠,操作更类似字符串拼接
    std::cout << "p1 = " << p1 << '\n'
              << "p2 = " << p2 << '\n'
              << "p3 = " << p3 << '\n'
              << "p3 = " << p4 << '\n';
}

output-注意p2的路径输出是没有/usr/lib和text.txt之间是没反斜杆的

p1 = "/usr/lib/text.txt"
p2 = "/usr/libtext.txt"
p3 = "/usr/lib/text.txt"
p3 = "/usr/lib/text.txt"
2.3 对路径文件名进行操作修改
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
 
int main()
{
    fs::path p = "foo/bar/old.txt";
    //判断是否存在文件名
    if(p.has_filename())
      std::cout << p.filename() << std::endl; //text.txt
    //替换文件名
    p.replace_filename("new.txt");
    std::cout << p.filename() << std::endl;
    //删除文件名
    p.remove_filename();
    std::cout << std::boolalpha << p.has_filename() << std::endl; //false
    return 0;
}

output:

"old.txt"
"new.txt"
false
2.4 对文件拓展名修改
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;

int main()
{
  fs::path p = "foo/bar/old.txt";
  fs::path p1 = "foo/bar";
  std::cout << std::boolalpha << p.has_extension() 
            << " " << p1.has_extension() << std::endl;
  
  //获取拓展名
  std::cout << "p extension     " << p.extension() << std::endl;

  //替换拓展名
  p.replace_extension("png");
  std::cout << "replace png     " << p << std::endl;

  //删除拓展名
  p.replace_extension("");
  std::cout << "del extension   " << p << std::endl;

  //添加拓展名
  p.replace_extension(".txt");
  std::cout << "add extension .txt "<< p << std::endl;
  return 0;
}
2.5 path 判断路径是否存在
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
 

 
int main()
{
    const fs::path sandbox{"sandbox"};
    fs::create_directory(sandbox);
    std::ofstream{sandbox/"file"}; // create regular file
 
    std::cout << std::boolalpha << fs::exists(sandbox) << std::endl; //true 目录路径
    std::cout << std::boolalpha << fs::exists(sandbox/"file")  << std::endl; //true 文件路径
    //不存在路径
    std::cout << std::boolalpha << fs::exists("/asd/asda") << std::endl;//false
 
    fs::remove_all(sandbox);
}

三、目录相关操作

3.1 创建目录和删除目录
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
 
int main()
{
    //设置当前路径 为 /tmp
    //相当于 cd /tmp
    fs::current_path(fs::temp_directory_path());
    //mkdir -p sandbox/1/2/a  递归创建目录
    fs::create_directories("./sandbox/1/2/a");
    //mkdir sandbox/1/2/b 创建目录
    fs::create_directory("./sandbox/1/2/b");
    fs::permissions("./sandbox/1/2/b", fs::perms::others_all, fs::perm_options::remove);
    //复制目录属性
    fs::create_directory("./sandbox/1/2/c", "./sandbox/1/2/b");
    std::system("ls -l sandbox/1/2");
    std::system("tree sandbox");
    //rm -rf sandbox
    fs::remove_all("sandbox");
}

output

total 12
drwxr-xr-x 2 cyy cyy 4096 Dec 19 13:09 a
drwxr-x--- 2 cyy cyy 4096 Dec 19 13:09 b
drwxr-x--- 2 cyy cyy 4096 Dec 19 13:09 c
sandbox
└── 1
    └── 2
        ├── a
        ├── b
        └── c

5 directories, 0 files
3.2 遍历指定目录所有内容,不包含"."和".."
int main()
{
    const std::filesystem::path sandbox{"sandbox"};
    std::filesystem::create_directories(sandbox/"dir1"/"dir2");
    std::ofstream{sandbox/"file1.txt"};
    std::ofstream{sandbox/"file2.txt"};

    //非递归遍历该目录下的内容
    std::cout << "directory_iterator:\n";
    // directory_iterator can be iterated using a range-for loop
    for (auto const& dir_entry : std::filesystem::directory_iterator{sandbox}) 
        std::cout << dir_entry.path() << '\n';

    //递归遍历该目录下所有内容
    std::cout << "\nrecursive_directory_iterator:\n";
    for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{sandbox}) 
        std::cout << dir_entry << '\n';
 
    // delete the sandbox dir and all contents within it, including subdirs
    // 递归删除该目录所有内容 相当于 rm -rf sandbox
    std::filesystem::remove_all(sandbox);
}

output

directory_iterator:
"sandbox/dir1"
"sandbox/file1.txt"
"sandbox/file2.txt"

recursive_directory_iterator:
"sandbox/dir1"
"sandbox/dir1/dir2"
"sandbox/file1.txt"
"sandbox/file2.txt"

四、文件类型判断

在filesystem库中使用枚举类型file_type对文件类型进行定义

常量 含义
none 文件状态尚未求值,或求值时发生错误
not_foud 找不到该文件
regular 常规文件(二进制、文本等)
directory 目录
symlink 符号链接
block 块(设备)
character 块(设备)
fifo 管道类型文件
socket socket
unknown 文件存在但类型不确定

测试用例

#include <cstdio>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
 
namespace fs = std::filesystem;
 
void demo_status(const fs::path& p, fs::file_status s)
{
    std::cout << p;
    switch (s.type())
    {
        case fs::file_type::none:
            std::cout << " has `not-evaluated-yet` type";
            break;
        case fs::file_type::not_found:
            std::cout << " does not exist";
            break;
        case fs::file_type::regular:
            std::cout << " is a regular file";
            break;
        case fs::file_type::directory:
            std::cout << " is a directory";
            break;
        case fs::file_type::symlink:
            std::cout << " is a symlink";
            break;
        case fs::file_type::block:
            std::cout << " is a block device";
            break;
        case fs::file_type::character:
            std::cout << " is a character device";
            break;
        case fs::file_type::fifo:
            std::cout << " is a named IPC pipe";
            break;
        case fs::file_type::socket:
            std::cout << " is a named IPC socket";
            break;
        case fs::file_type::unknown:
            std::cout << " has `unknown` type";
            break;
        default:
            std::cout << " has `implementation-defined` type";
            break;
    }
    std::cout << '\n';
}
 
int main()
{
    // create files of different kinds
    fs::create_directory("sandbox");
    fs::create_directory("sandbox/dir");
    std::ofstream{"sandbox/file"}; // create regular file
    fs::create_symlink("file", "sandbox/symlink");
 
    mkfifo("sandbox/pipe", 0644);
    sockaddr_un addr;
    addr.sun_family = AF_UNIX;
    std::strcpy(addr.sun_path, "sandbox/sock");
    int fd = socket(PF_UNIX, SOCK_STREAM, 0);
    bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof addr);
 
    // demo different status accessors
    for (auto it{fs::directory_iterator("sandbox")}; it != fs::directory_iterator(); ++it)
        demo_status(*it, it->symlink_status()); // use cached status from directory entry
    demo_status("/dev/null", fs::status("/dev/null")); // direct calls to status
    demo_status("/dev/sda", fs::status("/dev/sda"));
    demo_status("sandbox/no", fs::status("/sandbox/no"));
 
    // cleanup (prefer std::unique_ptr-based custom deleters)
    close(fd);
    fs::remove_all("sandbox");
}

四、参考

标签:std,fs,filesystem,C++,sandbox,使用,txt,path,include
From: https://www.cnblogs.com/chen-pi/p/17926944.html

相关文章

  • 如何使用ps抠图(两种扣图方法)
    PS抠图的方法有很多种,以下是其中两种常用的方法:方法一:适用于背景颜色单一、较为简单的图片。选中魔棒工具/魔术橡皮擦,点击背景,出现选区,点击Delete键删除。点击快速选择工具,沿着所需图形的边缘点击。该工具会自动识别图形的边缘并形成选区。方法二:适用于背景颜色复杂、需要精......
  • Java Junit 单元测试使用示范(带截图)
    依赖包junit-4.7.jar@Test注解packagejunit;importorg.junit.Test;/***选中add,右键运行add()*/publicclassDemo1{@Testpublicvoidadd(){inta=10;intb=13;intsum=a+b;System.out.println(sum);}......
  • Python 如何在测试中使用 Mock
    Mock概念mock的意思是模拟,也就是模拟接口返回的信息,用已有的信息替换它需要返回的信息,从实现对所依赖的模块的测试。一般有两种场景:前端对后端接口的mock,后端服务之间的测试中涉及的mock,常常发生在单元测试的时候。前端mock可以通过一些工具来完成:使用抓包工具Fiddler,Charles来......
  • Ubuntu上安装、使用Redis的详细教程
    sudoapt-getupdatesudoapt-getinstallredis启动方式二systemctlstartredis-server启动方式三serviceredis-serverstart重启redisserviceredis-serverrestart关闭redisserviceredis-serverstop查看redis状态serviceredis-serverstatus4、在宿主机连接redis根据以......
  • 无涯教程-PostgreSQL - 连接C/C++
    本教程将使用libpqxx库,该库是PostgreSQL的官方C++客户端API。libpqxx的源代码在BSD许可下可用,因此您可以免费下载,将其传递给他人,进行更改,出售,将其包含在自己的代码中,并与选择的任何人共享您的更改。安装Libpqxx可以从以下链接下载最新版本的libpqxx:下载Libpqxx。因此,下载......
  • 使用git工具将本地文件上传到github仓库
    1、先创建一个文件夹2、gitinit:把文件夹变成git可管理的仓库3、gitadd.:“.”表示当前文件夹下所有内容都提交,也可以通过gitaddFileName/FolderName提交指定的文件或文件夹把文件添加到缓存区4、gitstatus:查看现在的状态5、gitcommit-m"description":把文件提交的本地......
  • 水星 SG108 PRO/1.0 网络端口镜像 使用流程
    水星SG108PRO/1.0网络端口镜像使用流程购买链接https://item.jd.com/100001913315.html水星智能网管交换机客户端应用程序1.0.3https://service.mercurycom.com.cn/download-1830.html如上图1是端口1ip172.16.106.602是端口2ip172.16.106.1106是网络接入口......
  • linux编译器:gcc/g++的使用
    原文连接:https://blog.csdn.net/weixin_72060925/article/details/131274627原文链接:https://blog.csdn.net/qq_65207641/article/details/128629904一、编辑器与编译器的区别vim是代码编辑器,代码编辑器的功能是让我们输入代码的。所以从这个角度出发,我们常见的记事本也可以......
  • MSSQL执行查询报错“使用 UNION、INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其
     MSSQL执行查询报错“使用 UNION、INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有相同数目的表达式。”报错截图: 根本原因如提示,列不一致,列的个数和列名,顺序都需要一致。 ......
  • 使用AI人声伴奏分离工具提取伴奏音乐
    随着人工智能技术的不断发展,AI在音乐制作领域的应用也越来越广泛。其中,AI人声伴奏分离技术已经成为音乐制作中的一项重要技术。给大家分享的这两款软件工具Replay和UVR,以及它们在音乐制作中的应用。大家不用担心不会安装,下载包里面附安装教程宝子们。UltimateVocalRemover(UVR)......