FileUnit.hpp

#ifndef FILE_UNIT_H_20220214
#define FILE_UNIT_H_20220214

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <boost/filesystem.hpp>
#include <LogHelper.h>

#include "utility/Utility.hpp"
#include "utility/ThreadPool.hpp"
#include "3rd_party/nlohmann/json.hpp"

using nJson = nlohmann::json;
namespace fs = boost::filesystem;

namespace node
{
class FileUnit
{
public:
    inline static bool
    CreateNewDirectory(const std::string& strDir)
    {
        if (IsDirExist(strDir))
        {
            return true;
        }
        return boost::filesystem::create_directories(strDir);
    }

    inline static bool
    CreateFile(const std::string& strAbsoluteFilePath)
    {
        try
        {
            boost::filesystem::path file(strAbsoluteFilePath);  // 创建一个path对象
            if (boost::filesystem::is_regular_file(file))
            {  // 判断文件是否已经存在
                std::cout << "File already exists!" << std::endl;
                return false;
            }
            else
            {
                boost::filesystem::create_directories(file.parent_path());  // 先创建路径
                std::ofstream ofs(file.string());                           // 创建文件
                ofs.close();
                std::cout << "File created successfully!" << std::endl;
                return true;
            }
        }
        catch (const std::exception& ex)
        {
            ECO_ERROR_STREAM("Create file failed, reason: " << ex.what());
            return false;
        }
    }

    inline static bool
    IsDirExist(const std::string& strDIr)
    {
        if (boost::filesystem::exists(strDIr) && boost::filesystem::is_directory(strDIr))
        {
            return true;
        }
        return false;
    }

    inline static bool
    IsFileExist(const std::string& file_name)
    {
        if (boost::filesystem::exists(file_name) && boost::filesystem::is_regular_file(file_name))
        {
            return true;
        }
        return false;
    }

    inline static bool
    IsAllFileNotEmpty(const std::string& file_name, const std::vector<std::string>& suffix)
    {
        bool ret = true;
        for (auto var : suffix)
        {
            std::string file_full_path = file_name + var;
            if (boost::filesystem::file_size(file_full_path) <= 0)
            {
                ECO_WARN("file \"%d\" is empty !!!", file_full_path.c_str());
                ret = false;
                break;
            }
        }
        return ret;
    }

    inline static uint32_t
    GetFileSize(const std::string& file_name)
    {
        uint32_t file_size = boost::filesystem::file_size(file_name);
        return file_size;
    }

    inline static std::string
    GetFileContent(const std::string& file_name)
    {
        if (!IsFileExist(file_name))
        {
            ECO_WARN("File %s not exist", file_name.c_str());
        }
        else
        {
            std::ifstream is(file_name);
            return { std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>() };
        }
        return std::string();
    }

    inline static std::vector<uint8_t>
    GetFileContentAsVector(const std::string& file_name)
    {
        if (!IsFileExist(file_name))
        {
            ECO_WARN("File %s not exist", file_name.c_str());
        }
        else
        {
            uint32_t file_size = GetFileSize(file_name);
            std::vector<uint8_t> buffer;
            buffer.resize(file_size);
            std::ifstream inFile(file_name, std::ios::binary);
            inFile.read((char*)buffer.data(), buffer.size());
            inFile.close();
            ECO_DEBUG("read div binary_size  = %d, file_size = %d", buffer.size(), file_size);
            return std::move(buffer);
        }
        return std::vector<uint8_t>();
    }

    inline static bool
    WriteContentToFile(const std::string& file_name, const std::string& content)
    {
        std::ofstream file(file_name, std::ios::binary | std::ios::out | std::ios::trunc);
        file << content;
        file.close();
        sync();
        return true;
    }

    /*使用boost filesystem实现*/
    template<typename T>
    inline static bool
    WriteToFileByBoost(const std::string& filename, const T& data)
    {
        ECO_INFO("[file]Write file: %s", filename.c_str());
        try
        {
            std::ofstream ofs(filename, std::ios::out | std::ios::binary);
            if (ofs.is_open())
            {
                ofs.write(reinterpret_cast<const char*>(data.data()), data.size());
                return true;
            }
            else
            {
                ECO_ERROR("The file cannot be opened.");
                return false;
            }
        }
        catch (const std::exception& ex)
        {
            ECO_ERROR_STREAM("An exception occurred when writing to the file: " << ex.what());
            return false;
        }
    }

    /**< 使用系统函数实现 */
    template<typename T>
    inline static bool
    WriteToFileBySystem(const std::string& filename, const T& data)
    {
        auto startTime = Utility::GetCurrentTime();
        if (!FileUnit::IsFileExist(filename))
        {
            if (!FileUnit::CreateFile(filename))
            {
                return false;
            }
        }

        ECO_INFO("[file]Try to write file: %s", filename.c_str());
        int fd;
        try
        {
            fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
            if (fd == -1)
            {
                ECO_ERROR("The file cannot be opened.");
                return false;
            }

            ssize_t bytesWritten = write(fd, data.data(), data.size());
            if (bytesWritten == -1)
            {
                close(fd);
                ECO_ERROR("An exception occurred when writing to the file.");
                return false;
            }

            auto func = [&](const int& fd) {
                int ret = fsync(fd);
                if (ret == -1)
                {
                    ECO_ERROR("An exception occurred when executing fsync.");
                    perror("An exception occurred when executing fsync.");
                }

                close(fd);
            };

            ThreadPool::instance().enqueue(func, fd);
        }
        catch (const std::exception& ex)
        {
            ECO_ERROR_STREAM("An exception occurred when writing to the file: " << ex.what());
            close(fd);
            return false;
        }

        auto endTime = Utility::GetCurrentTime();
        ECO_WARN_NEW("Exec WriteToFileBySystem Func time: {}ms", endTime - startTime);

        return true;
    }


    inline static bool
    WriteVectorContentToFile(const std::string& file_name, const std::vector<uint8_t>& content)
    {

        std::ofstream file(file_name, std::ios::binary | std::ios::out | std::ios::trunc);
        file.write((char*)content.data(), content.size());
        file.close();
        sync();
        int file_size = GetFileSize(file_name);
        ECO_DEBUG("write div binary_size  = %d, file_size = %d", content.size(), file_size);
        return true;
    }

    /**< 删除目录下所有文件 */
    inline static void
    RemoveAllFilesInDir(const std::string& strDIr, bool isRemoveDir = false)
    {
        boost::filesystem::path dir(strDIr);

        if (boost::filesystem::is_directory(dir))
        {
            // 遍历目录中的文件和子目录
            for (boost::filesystem::directory_iterator iter(dir), end_iter; iter != end_iter; ++iter)
            {
                const boost::filesystem::path& path = iter->path();
                if (boost::filesystem::is_directory(path))
                {
                    // 如果是子目录,则递归删除子目录下的文件
                    if (isRemoveDir)
                        RemoveAllFilesInDir(path.string());
                }
                else
                {
                    // 如果是文件,则删除该文件
                    boost::filesystem::remove(path);
                }
            }

            // 如果目录为空,则删除该目录
            if (isRemoveDir && boost::filesystem::is_empty(dir))
            {
                boost::filesystem::remove(dir);
            }
        }
    }

    inline static nJson
    LoadFile2Json(const std::string& strFullPath)
    {
        ECO_INFO_NEW("Try to load file: '{}'", strFullPath);
        if (strFullPath.empty())
        {
            ECO_ERROR("The path of file is empty.");
            return {};
        }
        if (!IsFileExist(strFullPath))
        {
            ECO_WARN("The file does not exist, '%s'", strFullPath.c_str());
            return {};
        }

        std::ifstream file(strFullPath);
        nJson rootJson;

        try
        {
            file >> rootJson;
            file.close();
        }
        catch (const std::exception& e)
        {
            file.close();
            ECO_ERROR("Parse config file 2 json failed, reason: \n%s", e.what());
            return {};
        }

        return rootJson;
    }

    inline static bool
    CopyDirFromTo(const std::string& srcAbsDir, const std::string& targetAbsDir)
    {
        fs::path sourceDir{ srcAbsDir };
        fs::path targetDir{ targetAbsDir };

        if (!fs::exists(targetDir))
        {
            ECO_WARN_NEW("[CopyDir] No such target directory: {}, create it...\n", targetDir.filename().c_str());
            fs::create_directory(targetDir);
        }

        for (fs::directory_entry& srcEntry : fs::recursive_directory_iterator(sourceDir))
        {
            fs::path relativePath = fs::relative(srcEntry.path(), sourceDir);
            fs::path destPath = targetDir / relativePath;
            try
            {
                if (fs::is_directory(srcEntry.path()))
                {
                    ECO_INFO("[CopyDir] try 2 create target sub directory: %s\n", targetDir.filename().c_str());
                    fs::create_directory(destPath);
                }
                else
                {
                    fs::copy_file(srcEntry.path(), destPath, fs::copy_option::overwrite_if_exists);
                }
            }
            catch (fs::filesystem_error& ex)
            {
                ECO_ERROR_NEW("[CopyDir] error, reason: {}\n", ex.what());
                return false;
            }
        }
        return true;
    }
};
}  // namespace node


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值