前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[现代C++]文件系统操作

[现代C++]文件系统操作

作者头像
程序员的园
发布2024-07-18 13:33:40
120
发布2024-07-18 13:33:40
举报
文章被收录于专栏:程序员的园——原创文章

作为一名QT开发工程师,对于QT的文件系统操作的便利性推崇备至,但在非QT程序中仅仅因为操作文件系统而集成QT库显得过于繁重。

C++17引入了std::filesystem,使得文件系统操作变得前所未有的便捷和高效。std::filesystem为我们提供了一套类型安全、异常友好的接口,让跨平台的文件和目录管理变得轻而易举。

前置条件

std::filesystem是C++17引入的新特性,所以编译器需支持C++17及以后版本。同时,文件系统操作的相应功能是在std中的filesystem命名空间内,所以在包含头文件<filesystem>的基础上,还要注意使用命名空间。

文件路径与路径操作

std::filesystem::path是std::filesystem中最核心的类,它代表文件或目录的路径。通过定义path类型的对象即可。该类型支持对于路径的检查,包括路径性质和路径存在性检查。见如下示例代码:

代码语言:javascript
复制
#include<filesystem>
namespacefs = std::filesystem;


fs::path filePath = "d://example.txt";
fs::path relativePath = "example.txt";
fs::path combinedPath =  "../subfolder"; 


//后缀名
if (filePath.has_extension())
{
    std::cout << "extension " << filePath.extension() << "\n";
}


//文件名
if (filePath.has_filename())
{
    std::cout << "filename " << filePath.filename() << "\n";
}


//绝对路径检查
if (filePath.is_absolute())
{
    std::cout << "Absolute path\n";
}


//相对路径检查
if (relativePath.is_relative())
{
    std::cout << "Relative path\n";
}


//存在性检查
if (fs::exists(filePath)) {
    std::cout << "Path exists.\n";
}

文件目录

std::filesystem支持文件夹的创建、移除,并支持文件夹存在性、文件夹的子文件夹检查,同时可以支持磁盘剩余空间、文件夹属性的检查。

代码语言:javascript
复制
std::cout<<"current path "<< fs::current_path().string()<<"\n";


//检查文件夹是否存在
//不存在则创建
if (!fs::exists("d://programer"))
{
    //父目录必须存在,否则会抛出异常
     //文件存在时,创建失败
    bool create_ret = fs::create_directory("d://programer");
    std::cout << "create create_directory of 'd://programer'  result " << create_ret << "\n";
}
else
{
    std::cout << "directory of 'd://programer'  has existed do not need create"<< "\n";
}


//检查当前文件夹是否存在子文件夹
if (!fs::path("d://programer").has_stem())
{
     //有子文件夹时使用remove方法会报错
    bool create_ret = fs::remove("d://programer");
    std::cout << "remove of 'd://programer'  result " << create_ret << "\n";
}
else
{
    std::cout << "directory of 'd://programer'  has stem, cannot use remove, so use remove_all " << "\n";
    //递归删除
    bool create_ret = fs::remove_all("d://programer");
    std::cout << "remove_all of 'd://programer'  result " << create_ret << "\n";
}



//递归创建目录,父目录不存在也可以正确创建
bool  create_ret = fs::create_directories("d://programer/pro/pro/hello");
std::cout<<"create create_directories of 'd://programer/pro/pro/hello'  result "<<create_ret << "\n";



create_ret = fs::remove_all("d://programer");
std::cout << "remove_all directories of 'd://programer/pro/pro/hello'  result " << create_ret << "\n";


  auto spaceinfo =  fs::space("D://");
  std::cout<<" available="<<spaceinfo.available / (1024 * 1024 * 1024) << //剩余空间
    " capacity=" << spaceinfo.capacity/(1024*1024*1024) << //总空间
    " free=" << spaceinfo.free / (1024 * 1024 * 1024) << "\n";//剩余空间


  auto status = fs::status("D://");
  std::cout << " type=" << (int)status.type() //类型,表征目录、socket等
    << " permissions=" << (int)status.permissions() << "\n";//权限,如读写等

同时支持文件夹的遍历,如下方法将遍历文件夹下的所有文件和文件夹。

代码语言:javascript
复制
for (constauto & entry : fs::directory_iterator("documents")) {
    std::cout << entry.path() << std::endl;
}

也支持文件/文件夹的复制和重命名,方法如下:

代码语言:javascript
复制
    fs::copy("d://111", "d://2221", fs::copy_options::overwrite_existing);
    fs::rename("d://111", "d://22222");

异常处理

std::filesystem操作会因为文件/文件夹不存在、已存在、权限不够等而出现异常,因此需要注意调用函数的标志位,如copy方法中的copy_options标志位;也需要注意处理异常,如下

代码语言:javascript
复制
try {
    fs::copy("source.txt", "destination.txt");
} catch (constfs::filesystem_error& ex) {
    std::cerr << "Exception caught (" << ex.what() << ")\n";
}

结语

std::filesystem不仅极大地简化了文件系统的操作,还通过类型安全和异常处理机制提升了代码的健壮性。它跨越了Windows、Linux、macOS等多个平台,使得跨平台开发更加便捷。掌握这一库,无疑会使你的C++项目在文件管理方面更加高效、可靠。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档