#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
FileUnit.hpp
最新推荐文章于 2024-08-28 14:35:43 发布