filesystem库——C++文件操作(基本语法,常用函数封装)

时间:2025-02-27 07:28:18

文章目录

  • 语法
    • 完整文件名,文件名称,扩展名,父目录
    • 判断,是否存在,是否为(文件,目录,符号链接)
    • 重命名/ 移动
      • 文件重命名
      • 目录重命名
    • 删除
      • 删除文件
      • 删除目录
    • 创建目录
      • 创建单个目录
      • 创建多级目录
    • 相对路径
  • 常用函数
    • (递归,非递归) 的获取指定目录下所有的(文件或者目录)的(绝对路径或者文件名称)
      • 递归的获取指定目录下的所有文件的(绝对路径,文件名)
      • 非递归的获取指定目录下的所有(文件或目录)的(绝对路径或文件名)
    • 判断目录是否存在,若不存在创建
    • 统计给定目录下的文件数量
    • 获取下载最新数据的发布时间
    • 获取指定目录下所有文件最后修改时间

头文件:#include <filesystem>
命令空间:using namespace std::filesystem;

语法

完整文件名,文件名称,扩展名,父目录

  • 输出路径中的文件名,即最后一位的
    字符串中的路径要是"D:\\wang\\code\\"或者"D:/wang/code/"
    std::string path = "D:/wang/code/";
    std::filesystem::path file(path);
    // 完整文件名
    std::string fullFileName = file.filename().string();
    // 获取文件名但不包括扩展名
    std::string fileName = file.filename().stem().string();
    // 获取文件扩展名,扩展名包含.这个符号
    std::string fileExtensionName = file.extension().string();

    std::cout << fullFileName << std::endl;         // 
    std::cout << fileName << std::endl;             // qwe
    std::cout << fileExtensionName << std::endl;    // .txt
	
    // 父目录
	std::filesystem::path parentPath = file.parent_path();

判断,是否存在,是否为(文件,目录,符号链接)

#include <iostream>
#include <filesystem>


int main() 
{
    std::filesystem::path path_to_check = "path/to/your/file_or_directory";

    // 检查路径是否存在
    if (std::filesystem::exists(path_to_check)) 
    {
        std::cout << "Path exists." << std::endl;

        // 检查路径是否为目录
        if (std::filesystem::is_directory(path_to_check)) 
        {
            std::cout << "It is a directory." << std::endl;
        }
        // 检查路径是否为文件
        else if (std::filesystem::is_regular_file(path_to_check)) 
        {
            std::cout << "It is a regular file." << std::endl;
        }
        // 检查路径是否为符号链接
        else if (std::filesystem::is_symlink(path_to_check)) 
        {
            std::cout << "It is a symbolic link." << std::endl;
        }
        // 其他类型的文件系统条目
        else 
        {
            std::cout << "It is some other type of filesystem entry." << std::endl;
        }
    } 
    else 
    {
        std::cout << "Path does not exist." << std::endl;
    }

    return 0;
}

重命名/ 移动

文件重命名

#include <iostream>
#include <filesystem>

int main() {
    std::filesystem::path old_filepath = "";
    std::filesystem::path new_filepath = "";

    if (std::filesystem::exists(old_filepath)) 
    {
        if (std::filesystem::rename(old_filepath, new_filepath)) 
        {
            std::cout << "File renamed successfully." << std::endl;
        } else 
        {
            std::cout << "Failed to rename the file." << std::endl;
        }
    } else {
        std::cout << "The file does not exist." << std::endl;
    }

    return 0;
}

目录重命名

#include <iostream>
#include <filesystem>

int main()
{
    std::filesystem::path old_dirpath = "old_directory";
    std::filesystem::path new_dirpath = "new_directory";

    if (std::filesystem::exists(old_dirpath) && std::filesystem::is_directory(old_dirpath))
    {
		std::error_code ec;  // 错误码,用于处理错误
		std::filesystem::rename(old_dirpath, new_dirpath, ec);
		if (!ec)
		{
			std::cout << "Directory removed successfully.\n";
		}
		else
		{
			std::cout << "Failed to rename the directory." << std::endl;

		}
    }
    else 
	{
        std::cout << "The directory does not exist." << std::endl;
    }

	return 0;
}

删除

string fi_path = "./data/";
std::filesystem::remove(std::filesystem::path(fi_path));

删除文件

#include <iostream>
#include <filesystem> // C++17 标准引入的文件系统库

int main() {
    std::string file_path = "/path/to/";

    try 
    {
        // 删除文件
        std::filesystem::remove(file_path);
        std::cout << "文件 " << file_path << " 已成功删除。\n";
    } 
    catch (const std::filesystem::filesystem_error& e)
    {
        std::cout << "删除文件时出错: " << e.what() << '\n';
    }
    return 0;
}

删除目录

#include <iostream>
#include <filesystem> // C++17 标准引入的文件系统库

int main() 
{
    std::string directory_path = "/path/to/directory";
    
    std::filesystem::path Dir(directory_path);
    // 删除目录及其内容
    std::error_code ec;  // 错误码,用于处理错误
    std::filesystem::remove_all(Dir, ec);
    if (!ec) 
    {
        std::cout << "Directory removed successfully.\n";
    }
    else 
    {
        std::cout << "Error removing directory : "<< Dir.string().c_str() << " " << ec.message() << "\n";
        return false;
    }

    return 0;
}

创建目录

创建单个目录

std::filesystem::create_directory()

  1. 用于创建单个目录
  2. 如果父目录不存在,那么这个函数将会失败,并且不会创建任何目录,create_directory 不会创建路径中缺失的任何中间目录
  3. 如果目录已存在,也不会报错。
#include <filesystem>

int main() 
{
    std::filesystem::path directoryPath = "/path/to/your/directory";

    try 
    {
        std::filesystem::create_directory(directoryPath);
        std::cout << "Directory created successfully: " << directoryPath << std::endl;
    } 
    catch (const std::exception& e) 
    {
        std::cout << "Error creating directory: " << e.what() << std::endl;
    }

    return 0;
}

创建多级目录

std::filesystem::create_directories()

  1. 用于递归创建目录路径中的所有目录,包括中间缺失的目录
  2. 如果目录已存在,它什么也不做,不引发异常
  3. 如果某个目录无法创建(例如由于权限问题),它将继续尝试创建其余的目录,而不会中止整个过程。
#include <filesystem>

namespace fs = std::filesystem;

int main() 
{
    std::filesystem::path directoryPath = "/path/to/your/directory";

    try 
    {
        std::filesystem::create_directories(directoryPath);
        std::cout << "Directories created successfully: " << directoryPath << std::endl;
    } 
    catch (const std::exception& e) 
    {
        std::cout << "Error creating directories: " << e.what() << std::endl;
    }

    return 0;
}

相对路径

获取一个路径相对于另一个路径的相对路径


std::filesystem::path file = "/data/compress/compress_dir/file2/";
std::filesystem::path dir = "/data/compress";

// 求 file 相对于 dir 的相对路径
std::filesystem::path relative_path = std::filesystem::relative(file, dir);
std::cout << relative_path.string() << std::endl;

// relative_path = "compress_dir\file2\"

常用函数

封装一个函数用于递归的获取指定目录下的所有文件的结对路劲 返回一个std::vectorstd::string 存储文件的就对路,传入一个std::string类型的路径地址,使用c++语言filesystem库

(递归,非递归) 的获取指定目录下所有的(文件或者目录)的(绝对路径或者文件名称)

/// <summary>
/// (递归,非递归) 的获取指定目录下所有的(文件或者目录)的(绝对路径或者文件名称)
/// </summary>
/// <param name="directoryPath">指定目录</param>
/// <param name="isFile">true:文件,false:目录</param>
/// <param name="returnFullPath">true表示完整路径,false仅表示名称</param>
/// <param name="recursive">false:非递归,true:递归</param>
/// <returns></returns>
std::vector<std::string> collectFileOrDirEntries(const std::string& directoryPath, bool isFile = true, bool returnFullPath = true, bool recursive = false)
{
    std::vector<std::string> entries;
    try
    {
        std::filesystem::path dirPath(directoryPath);
        if (recursive)  // 递归
        {
            for (auto& entry : std::filesystem::recursive_directory_iterator(dirPath))
            {
                if ((isFile && entry.is_regular_file()) || (!isFile && entry.is_directory()))
                {
                    if (returnFullPath)
                    {
                        entries.push_back(entry.path().string());
                    }
                    else
                    {
                        entries.push_back(entry.path().filename().make_preferred().string());
                    }
                }
            }
        }
        else // 非递归
        {
            for (auto& entry : std::filesystem::directory_iterator(dirPath))
            {
                if ((isFile && entry.is_regular_file()) || (!isFile && entry.is_directory()))
                {
                    if (returnFullPath)
                    {
                        entries.push_back(entry.path().string());
                    }
                    else
                    {
                        entries.push_back(entry.path().filename().make_preferred().string());
                    }
                }
            }
        }
    }
    catch (const std::filesystem::filesystem_error& e)
    {
        std::cout << "Error accessing directory: " << e.what() << std::endl;
    }

    return entries;
}

递归的获取指定目录下的所有文件的(绝对路径,文件名)


//  递归的获取指定目录下的所有文件的绝对路径
std::vector<std::string> recursiveCollectAllFilePaths(const std::string& directoryPath)
{
    std::vector<std::string> filePaths;
    std::vector<std::string> dirPaths;
    try
    {
        std::filesystem::path dirPath(directoryPath);
        // 使用递归目录迭代器遍历目录
        for (auto& entry : std::filesystem::recursive_directory_iterator(dirPath))
        {
            if (entry.is_regular_file()) // 检查是否为普通文件
            { 
                filePaths.push_back(entry.path().string());                // 绝对路径
                // filePaths.push_back(().filename().string());      // 文件名称
            }
            // else if (entry.is_directory()) // 检查是否为目录
            // {
            //     //dirPaths.push_back(().string());                // 绝对路径
            //      dirPaths.push_back(().filename().string());      // 目录名称
            // }
        }
    }
    catch (const std::filesystem::filesystem_error& e)
    {
        // 处理任何文件系统相关的异常
        std::cout << "Error accessing directory: " << e.what() << std::endl;
    }

    return filePaths;
}

非递归的获取指定目录下的所有(文件或目录)的(绝对路径或文件名)

std::vector<std::string> collectAllFilePaths(const std::string& directoryPath)
{
    std::vector<std::string> filePaths;
    std::vector<std::string> dirPaths;
    try
    {
        std::filesystem::path dirPath(directoryPath);
        for (auto& entry : std::filesystem::directory_iterator(dirPath))
        {
            if (entry.is_regular_file()) // 检查是否为普通文件
            { 
                filePaths.push_back(entry.path().string());                 // 绝对路径
                // filePaths.push_back(().filename().string());      // 文件名称
            }
            // else if (entry.is_directory()) // 检查是否为目录
            // {
            //     //dirPaths.push_back(().string());                // 绝对路径
            //      dirPaths.push_back(().filename().string());      // 目录名称
            // }
        }
    }
    catch (const std::filesystem::filesystem_error& e)
    {
        // 处理任何文件系统相关的异常
        std::cout << "Error accessing directory: " << e.what() << std::endl;
    }

    return filePaths;
}

判断目录是否存在,若不存在创建

#include <iostream>
#include <filesystem>

bool createDirectoryIfNotExists(const std::string& directoryPath) 
{
    std::filesystem::path path(directoryPath);

    if (!std::filesystem::exists(path)) 
    {
        try 
        {
            std::filesystem::create_directories(path);
            if (std::filesystem::exists(path)) 
            {
            		return true; // 创建目录成功	
            }
            else
            {
            	return false;
            }
            
        } 
        catch (const std::filesystem::filesystem_error& ex) 
        {
            std::cout << "Error creating directory: " << ex.what() << std::endl;
            return false; // 创建目录失败
        }
    } else 
    {
        return true; // 目录已存在
    }
}

int main() {
    std::string outputDirectory = "path/to/your/directory";
    
    if (CreateDirectoryIfNotExists(outputDirectory)) {
        std::cout << "Directory created or already exists: " << outputDirectory << std::endl;
    } else {
        std::cout << "Failed to create directory: " << outputDirectory << std::endl;
    }

    return 0;
}

统计给定目录下的文件数量

int count_files(const std::string& directory_path)
{
    int file_count = 0;

    // 检查目录是否存在
    if (std::filesystem::exists(directory_path) && std::filesystem::is_directory(directory_path))
    {
        // 遍历目录下的所有条目
        for (const auto& entry : std::filesystem::directory_iterator(directory_path))
        {
            // 检查是否为文件
            if (std::filesystem::is_regular_file(entry.status()))
            {
                ++file_count;
            }
        }
    }
    else
    {
        std::cout << "指定目录不存在或不是一个目录。" << std::endl;
    }
    return file_count;
}

获取下载最新数据的发布时间

/// <summary>
/// 获取下载最新数据的发布时间
/// </summary>
/// <param name="directory_path">如APCP目录</param>
/// <returns></returns>
std::string get_latest_data_pub_time(const std::string& directory_path)
{
	std::string latest_tm = "";
	// 定义时间格式的正则表达式
	std::regex time_regex(R"(\d{10})"); // 匹配10位数字

	// 检查目录是否存在
	if (std::filesystem::exists(directory_path) && std::filesystem::is_directory(directory_path))
	{
		// 遍历目录下的所有条目
		for (const auto& entry : std::filesystem::directory_iterator(directory_path))
		{
			// 检查是否为目录
			if (std::filesystem::is_directory(entry.status()))
			{
				if (entry.path().filename().string() > latest_tm && std::regex_match(entry.path().filename().string(), time_regex))
				{
					latest_tm = entry.path().filename().string();
				}
			}
		}
	}
	else
	{
		std::cout << directory_path << ": 目录不存在或不是一个目录" << std::endl;
	}

	return latest_tm;
}

获取指定目录下所有文件最后修改时间

#include <filesystem>
#include <chrono>

std::map<std::string ,std::string> getLastModifiedTimesInDirectory(const std::string& path)
{
    std::map<std::string, std::string> path_tm;
    for (const auto& entry : std::filesystem::directory_iterator(path))
    {
        if (entry.is_regular_file())
        {
            std::filesystem::file_time_type modificationTime = entry.last_write_time();
            auto sys_time = std::chrono::system_clock::now() + (modificationTime - std::filesystem::file_time_type::clock::now());
            std::time_t t = std::chrono::system_clock::to_time_t(sys_time);
            std::tm* ptm = std::localtime(&t); // 创建 tm 结构体

            // 定义一个足够大的字符数组来保存时间字符串
            char buffer[20];
            std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm); // 19个字节的格式
            path_tm[entry.path().string()] = buffer;
            std::cout << "File: " << entry.path().string() << ", Last modified: " << buffer << '\n';
        }
    }
    return path_tm;
}