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结果输出的差异

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值