1. 路径
使用 std::filesystem::path
类来表示文件路径.
#include
#include
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
#include
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
#include
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
#include
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
#include
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(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
#include
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
#include
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
#include
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
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
namespace fs = std::filesystem;
int main()
{
// 只能删除文件或空目录
fs::remove(fs::path("E:\\a\\b\\c\\d"));
// 递归删除子目录(非空亦可)
fs::remove_all(fs::path("E:\\a"));
}
9. 拷贝文件
也可以拷贝目录.
#include
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
#include
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(si.capacity) << ' '
<< "│ " << std::setw(width) << static_cast(si.free) << ' '
<< "│ " << std::setw(width) << static_cast(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)\\"