关于c++:C标准库文件系统

8次阅读

共计 6653 个字符,预计需要花费 17 分钟才能阅读完成。

1. 门路

应用 std::filesystem::path 类来示意文件门路.

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{fs::path p1("E:\\");
    fs::path p2(p1 / "Program Files (x86)" / "Tesseract-OCR");

    std::cout << p2;

    // 判断门路是否存在
    if (fs::exists(p2))
    {std::cout << "exists.\n";}
    else
    {std::cout << "does not exists.\n";}
}
"E:\\Program Files (x86)\\Tesseract-OCR" exists.

获取、切换当前工作门路:

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    // 打印当前工作门路
    std::cout << fs::current_path() << '\n';

    // 切换当前工作门路
    fs::current_path(fs::path("C:\\"));
    std::cout << fs::current_path() << '\n';}
"E:\\repos\\data-structure\\data-structure"
"C:\\"

2. 文件信息

std::filesystem::file_status 类中蕴含了文件类型和权限信息.

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

void printFileType(const fs::file_type& type)
{switch (type)
    {
    case fs::file_type::none: std::cout << "It has `not-evaluated-yet` type"; break;
    case fs::file_type::not_found: std::cout << "It does not exist"; break;
    case fs::file_type::regular: std::cout << "It is a regular file"; break;
    case fs::file_type::directory: std::cout << "It is a directory"; break;
    case fs::file_type::symlink: std::cout << "It is a symlink"; break;
    case fs::file_type::block: std::cout << "It is a block device"; break;
    case fs::file_type::character: std::cout << "It is a character device"; break;
    case fs::file_type::fifo: std::cout << "It is a named IPC pipe"; break;
    case fs::file_type::socket: std::cout << "It is a named IPC socket"; break;
    case fs::file_type::unknown: std::cout << "It has `unknown` type"; break;
    default: std::cout << "It has `implementation-defined` type"; break;
    }
    std::cout << '\n';
}

void printFilePermissions(const fs::perms& p)
{std::cout << ((p & fs::perms::owner_read) != fs::perms::none ? "r" : "-")
              << ((p & fs::perms::owner_write) != fs::perms::none ? "w" : "-")
              << ((p & fs::perms::owner_exec) != fs::perms::none ? "x" : "-")
              << ((p & fs::perms::group_read) != fs::perms::none ? "r" : "-")
              << ((p & fs::perms::group_write) != fs::perms::none ? "w" : "-")
              << ((p & fs::perms::group_exec) != fs::perms::none ? "x" : "-")
              << ((p & fs::perms::others_read) != fs::perms::none ? "r" : "-")
              << ((p & fs::perms::others_write) != fs::perms::none ? "w" : "-")
              << ((p & fs::perms::others_exec) != fs::perms::none ? "x" : "-")
              << '\n';
}

int main()
{fs::path path("E:\\Program Files (x86)\\Tesseract-OCR");
    fs::file_status stat(fs::status(path));

    // 文件类型
    printFileType(stat.type());

    // 文件拜访权限
    printFilePermissions(stat.permissions());
}
It is a directory
rwxrwxrwx

判断文件类型时也能够应用如下函数:

bool is_block_file(std::filesystem::file_status s) noexcept;
bool is_character_file(std::filesystem::file_status s) noexcept;
bool is_directory(std::filesystem::file_status s) noexcept;
bool is_empty(const std::filesystem::path& p);
bool is_fifo(std::filesystem::file_status s) noexcept;

// Equivalent to exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s)
bool is_other(std::filesystem::file_status s) noexcept;

bool is_regular_file(std::filesystem::file_status s) noexcept;
bool is_socket(std::filesystem::file_status s) noexcept;
bool is_symlink(std::filesystem::file_status s) noexcept;

3. 文件大小

以字节为单位.

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{fs::path path("E:\\ 文档 \\tmp.txt");

    // 打印文件大小
    std::uintmax_t size = fs::file_size(path);
    std::cout << size << "bytes\n";

    // 批改文件大小:截断或应用 0 进行填充
    fs::resize_file(path, size >> 1);
    size = fs::file_size(path);
    std::cout << size << "bytes\n";
}
3175 bytes
1587 bytes

4. 文件工夫

文件最初批改工夫:

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

void printLastWriteTime(const fs::file_time_type& ft)
{auto duration(ft.time_since_epoch());
    std::time_t t = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
    std::cout << "File write time is" << std::asctime(std::localtime(&t));
}

int main()
{fs::path path("E:\\ 文档 \\tmp.txt");
    printLastWriteTime(fs::last_write_time(path));
}
File write time is Wed Aug 22 10:07:28 2390

5. 文件重命名

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{fs::path oldPath("E:\\ 文档 \\tmp1.txt");
    fs::path newPath("E:\\ 文档 \\temp1.txt");

    std::cout << std::boolalpha << fs::exists(newPath) << '\n';

    fs::rename(oldPath, newPath);

    std::cout << std::boolalpha << fs::exists(newPath) << '\n';
}
false
true

6. 遍历目录

非递归遍历:

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{fs::path dir("E:\\tmp\\test");
    
    fs::directory_iterator it(dir);
    for (const auto& entry : it)
    {std::cout << entry.path().filename() << ":";

        if (entry.is_directory())
        {std::cout << "directory\n";}
        else if (entry.is_regular_file())
        {std::cout << "regular\n";}
        else
        {std::cout << "other\n";}
    }
}
"a.mp4": regular
"dir": directory
"test.py": regular

递归遍历(深度优先):

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{fs::path dir("E:\\tmp\\test");
    
    fs::recursive_directory_iterator it(dir);
    for (const auto& entry : it)
    {std::cout << entry.path() << ":";

        if (entry.is_directory())
        {std::cout << "directory\n";}
        else if (entry.is_regular_file())
        {std::cout << "regular\n";}
        else
        {std::cout << "other\n";}
    }
}
"E:\\tmp\\test\\a.mp4": regular
"E:\\tmp\\test\\dir": directory
"E:\\tmp\\test\\dir\\b.mp4": regular
"E:\\tmp\\test\\dir\\test.c": regular
"E:\\tmp\\test\\test.py": regular

7. 创立目录

#include <filesystem>

namespace fs = std::filesystem;

int main()
{const fs::path dir("E:\\a\\b\\c");
    
    // 主动创立缺失的父目录
    fs::create_directories(dir);

    // 不会主动创立缺失的父目录
    fs::create_directory(dir / "d");
}

8. 删除门路

#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    // 只能删除文件或空目录
    fs::remove(fs::path("E:\\a\\b\\c\\d"));

    // 递归删除子目录(非空亦可)fs::remove_all(fs::path("E:\\a"));
}

9. 拷贝文件

也能够拷贝目录.

#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    const auto options = fs::copy_options::recursive | fs::copy_options::update_existing;

    fs::copy(fs::path("E:\\tmp\\Back"), fs::path("E:\\tmp\\Back2"), options);
}

拷贝选项:

enum class copy_options {

    none = /* unspecified */,
    skip_existing = /* unspecified */,
    overwrite_existing = /* unspecified */,
    update_existing = /* unspecified */,
    recursive = /* unspecified */,

    // Copy symlinks as symlinks, not as the files they point to.
    copy_symlinks = /* unspecified */,

    skip_symlinks = /* unspecified */,
    directories_only = /* unspecified */,

    // Instead of creating copies of files, create symlinks pointing to the originals.
    create_symlinks = /* unspecified */,

    // Instead of creating copies of files, create hardlinks that resolve to the same files as the originals.
    create_hard_links = /* unspecified */
};

10. 磁盘空间

std::filesystem::space_info 类中蕴含了磁盘空间信息(以字节为单位).

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

void printSpaceInfo(const fs::path& dir)
{
    constexpr int width = 14;

    std::cout << std::left;
    for (const auto s : { "Capacity", "Free", "Available", "Dir"})
    {std::cout << "│" << std::setw(width) << s << ' ';
    }
    std::cout << '\n';

    fs::space_info si(fs::space(dir));
    std::cout
        << "│" << std::setw(width) << static_cast<std::intmax_t>(si.capacity) << ' '
        << "│" << std::setw(width) << static_cast<std::intmax_t>(si.free) << ' '
        << "│" << std::setw(width) << static_cast<std::intmax_t>(si.available) << ' '
        << "│" << dir << '\n';
}

int main()
{fs::path dir("E:\\Program Files (x86)\\");
    printSpaceInfo(dir);
}
│ Capacity       │ Free           │ Available      │ Dir
│ 392730505216   │ 263828779008   │ 263828779008   │ "E:\\Program Files (x86)\\"
正文完
 0