C++17中std::filesystem::directory_entry的使用

C++17引入了std::filesystem库 (文件系统库, filesystem library)。这里整理下std::filesystem::directory_entry的使用。

std::filesystem::directory_entry,目录项,获取文件属性 。此directory_entry类主要用法包括:

(1).构造函数、operator=、assign:赋值;

(2).replace_filename: 更改目录项的文件名;

(3).path: 返回std::filesystem::path对象;

(4).exists: 检查指定的目录项是否存在

(5).is_block_file、is_character_file: 检查目录项是否是块设备(block device)、字符设备(character device);

(6).is_directory: 检查目录项是否是目录;

(7).is_fifo: 检查目录项是否是命令管道;

(8).is_other: 检查目录项是否是其它文件(不是常规文件、目录或符号链接);

(9).is_regular_file: 检查目录项是否是常规文件;

(10).is_socket: 检查目录项是否是命名套接字;

(11).is_symlink: 检查目录项是否是符号链接;

(12).file_size: 获取目录项指定的文件大小

(13).last_write_time:获取目录项最后修改时间

以下为测试代码:注意windows和linux结果输出的差异

cpp 复制代码
namespace {

float get_file_size(std::uintmax_t size, std::string& suffix)
{
	float s1 = size / 1024. / 1024 / 1024;
	float s2 = size / 1024. / 1024;
	float s3 = size / 1024.;

	if (s1 > 1) {
		suffix = " GB";
		return s1;
	}
	if (s2 > 1) {
		suffix = " MB";
		return s2;
	}
	if (s3 > 1) {
		suffix = " KB";
		return s3;
	}
	suffix = " Bytes";
	return size;
}

std::string to_time_t(std::filesystem::file_time_type tp)
{
	using namespace std::chrono;
	auto sctp = time_point_cast<system_clock::duration>(tp - std::filesystem::file_time_type::clock::now() + system_clock::now());
	auto tt = system_clock::to_time_t(sctp);

	std::tm* gmt = std::localtime(&tt); // UTC: std::gmtime(&tt);
	std::stringstream buffer;
	buffer << std::put_time(gmt, "%Y-%m-%d %H:%M:%S");
	return buffer.str();
}

} // namespace

int test_filesystem_directory_entry()
{
	namespace fs = std::filesystem;

	// 1. construct,operator=,assign
	fs::directory_entry d1{ fs::current_path() };
	fs::directory_entry d2 = d1;
	fs::directory_entry d3;
	d3.assign(fs::current_path());
	if ((d1 == d2) && (d1 == d3))
		std::cout << "they are equal" << std::endl; // they are equal
	// windows: d1:"E:\\GitCode\\Messy_Test\\prj\\x86_x64_vc12\\CppBaseTest"
	// linux: d1:"/home/spring/GitCode/Messy_Test/prj/linux_cmake_CppBaseTest"
	std::cout << "d1:" << d1 << std::endl;

	// 2. replace_filename
	d1.replace_filename("C++17Test");
	// windows: d1:"E:\\GitCode\\Messy_Test\\prj\\x86_x64_vc12\\C++17Test"
	// linux: d1:"/home/spring/GitCode/Messy_Test/prj/C++17Test"
	std::cout << "d1:" << d1 << std::endl;

	// 3. path
	fs::path p1 = d1.path();
	// windows: p1:"E:\\GitCode\\Messy_Test\\prj\\x86_x64_vc12\\C++17Test"
	// linux: p1:"/home/spring/GitCode/Messy_Test/prj/C++17Test"
	std::cout << "p1:" << p1 << std::endl;

	// 4. exists
	for (const auto& str : { "C:\\Program Files (x86)", "/usr/local" , "E:\\GitCode\\xxx", "/usr/xxx"}) {
		fs::directory_entry entry{ str };
		/* windows:
			directory entry: "C:\\Program Files (x86)":exists
			directory entry: "/usr/local":does not exist
			directory entry: "E:\\GitCode\\xxx":does not exist
			directory entry: "/usr/xxx":does not exist */
		/* linux:
			directory entry: "C:\\Program Files (x86)":does not exist
			directory entry: "/usr/local":exists
			directory entry: "E:\\GitCode\\xxx":does not exist
			directory entry: "/usr/xxx":does not exist
		*/
		std::cout << "directory entry: " << entry << (entry.exists() ? ":exists\n" : ":does not exist\n");
	}

	// 5. is_block_file,is_character_file,is_directory,is_fifo,is_other,is_regular_file,is_socket,is_symlink
	for (const auto& str : { "/dev/null", "C:\\Program Files (x86)", "/usr/include/time.h", "C:\\MinGW\\bin\\c++filt.exe",
		"/usr/bin/g++", "/dev/block/11:0"}) {
		fs::directory_entry entry{ str };
		/* windows:
			"C:\\Program Files (x86)" is a directory
			"C:\\MinGW\\bin\\c++filt.exe" is a regular_file */
		/* linux:
			"/dev/null" is a character device
			"/dev/null" is an other file
			"/usr/include/time.h" is a regular_file
			"/usr/bin/g++" is a regular_file
			"/usr/bin/g++" is a symlink
			"/dev/block/11:0" is a block device
			"/dev/block/11:0" is an other file
			"/dev/block/11:0" is a symlink */
		if (entry.is_block_file())
			std::cout << entry << " is a block device" << std::endl;
		if (entry.is_character_file())
			std::cout << entry << " is a character device" << std::endl;
		if (entry.is_directory())
			std::cout << entry << " is a directory" << std::endl;
		if (entry.is_fifo())
			std::cout << entry << " is a FIFO" << std::endl;
		if (entry.is_other())
			std::cout << entry << " is an other file" << std::endl;
		if (entry.is_regular_file())
			std::cout << entry << " is a regular_file" << std::endl;
		if (entry.is_socket())
			std::cout << entry << " is a named socket" << std::endl;
		if (entry.is_symlink())
			std::cout << entry << " is a symlink" << std::endl;
	}

	// 6. file_size, last_write_time
	for (const auto& str : { "/usr/bin/g++", "D:\\FSCapture.exe", "D:\\DownLoad\\tmp.txt", "/usr/bin/cmake", "E:\\yulong.mp4"}) {
		fs::directory_entry entry{ str };
		/* windows:
			"D:\\FSCapture.exe" size: 2.82 MB
			"D:\\FSCapture.exe" last write time: 2016-03-29 09:26:26
			"D:\\DownLoad\\tmp.txt" size: 10 Bytes
			"D:\\DownLoad\\tmp.txt" last write time: 2023-09-26 09:00:35
			"E:\\yulong.mp4" size: 1.35 GB
			"E:\\yulong.mp4" last write time: 2023-08-19 22:42:56 */
		/* linux:
			"/usr/bin/g++" size: 910.82 KB
			"/usr/bin/g++" last write time: 2023-05-13 15:52:47
			"/usr/bin/cmake" size: 6.43 MB
			"/usr/bin/cmake" last write time: 2022-08-17 18:44:05 */
		if (entry.is_regular_file()) {
			std::string suffix;
			auto value = get_file_size(entry.file_size(), suffix);
			if (suffix == " Bytes")
				std::cout << entry << " size: " << static_cast<int>(value) << suffix << std::endl;
			else
				std::cout << entry << " size: " << std::fixed << std::setprecision(2) << value << suffix << std::endl;

			std::cout << entry << " last write time: " << to_time_t(entry.last_write_time()) << std::endl;
		}
	}

	return 0;
}

执行结果如下图所示:

GitHubhttps://github.com/fengbingchun/Messy_Test

相关推荐
PleaSure乐事3 个月前
【Node.js】内置模块FileSystem的保姆级入门讲解
javascript·node.js·es6·filesystem
tekin7 个月前
go语言内置预编译 //go:embed xxx 使用详解
开发语言·后端·golang·预编译·filesystem·fs·embed
大隐隐于野1 年前
百度沧海文件存储CFS推出新一代Namespace架构
filesystem·cfs
恋喵大鲤鱼1 年前
C++ 创建文件并写入内容
c++·filesystem
fengbingchun1 年前
在Ubuntu 18.04上支持C++17的std::filesystem的方法
filesystem