1. 关键词
C++ 文件系统操作 读取纯文本文件 写入纯文本文件 跨平台
2. fileutil.h
#pragma once
#include <string>
#include <cstdio>
#include <cstdint>
#include "filetype.h"
#include "filepath.h"
namespace cutl
{
/**
* @brief The file guard class to manage the FILE pointer automatically.
* file_guard object can close the FILE pointer automatically when his scope is exit.
*/
class file_guard
{
public:
/**
* @brief Construct a new file guard object
*
* @param file the pointer of the FILE object
*/
explicit file_guard(FILE *file);
/**
* @brief Destroy the file guard object
*
*/
~file_guard();
/**
* @brief Get the FILE pointer.
*
* @return FILE*
*/
FILE *getfd() const;
private:
FILE *file_;
};
/**
* @brief Read the text content of a file.
*
* @param path the filepath of the file to be read
* @param max_read_size the maximum size to be read, default is 4096 bytes.
*
* If the file size is larger than max_read_size, only the first max_read_size bytes will be read. otherwise, the whole file will be read.
*
* @return text content of the file
*/
std::string readtext(const filepath &path, uint64_t max_read_size = 4096);
/**
* @brief Write the text content to a file.
*
* @param path the filepath of the file to be written
* @param content text content to be written to the file
* @return true if the content is written successfully, false otherwise.
*/
bool writetext(const filepath &path, const std::string &content);
} // namespace cutl
3. fileutil.cpp
#include <cstdio>
#include <map>
#include <iostream>
#include <cstring>
#include <sys/stat.h>
#include "fileutil.h"
#include "inner/logger.h"
#include "inner/filesystem.h"
#include "strutil.h"
namespace cutl
{
file_guard::file_guard(FILE *file)
: file_(file)
{
}
file_guard::~file_guard()
{
if (file_)
{
// CUTL_DEBUG("close file");
int ret = fclose(file_);
if (ret != 0)
{
CUTL_ERROR("fail to close file, ret" + std::to_string(ret));
}
file_ = nullptr;
}
// ROBOLOG_DCHECK(file_ == nullptr);
}
FILE *file_guard::getfd() const
{
return file_;
}
std::string readtext(const filepath &path, uint64_t max_read_size)
{
file_guard fg(fopen(path.str().c_str(), "r"));
if (fg.getfd() == nullptr)
{
CUTL_ERROR("open file failed for " + path.str());
return "";
}
// 从文件系统的文档信息里读取文件大小,性能更高
auto data_len = filesize(path, true);
// 公国文件操作的方式和获取文件大小
// fseek(fg.getfd(), 0, SEEK_END);
// size_t data_len = static_cast<size_t>(ftell(fg.getfd()));
// rewind(fg.getfd());
CUTL_DEBUG("file size: " + std::to_string(data_len) + ", file: " + path.str());
// get read size
if (data_len > max_read_size)
{
data_len = max_read_size;
CUTL_WARN("file size is large than " + std::to_string(max_read_size) + ", file:" + path.str());
}
char *buffer = new char[data_len + 1];
if (buffer == nullptr)
{
CUTL_ERROR("buffer alloc failed, data_len:" + std::to_string(data_len));
return "";
}
size_t read_len = static_cast<size_t>(fread(buffer, 1, data_len, fg.getfd()));
if (read_len < data_len)
{
CUTL_ERROR("read file failed, only read " + std::to_string(read_len) + " bytes for " + path.str());
}
buffer[read_len] = '\0';
auto text = std::string(buffer);
delete[] buffer;
return text;
}
// https://en.cppreference.com/w/cpp/header/cstdio
bool writetext(const filepath &path, const std::string &content)
{
// std::lock_guard
file_guard fg(fopen(path.str().c_str(), "w"));
if (fg.getfd() == nullptr)
{
CUTL_ERROR("open file failed for " + path.str() + ", error: " + strerror(errno));
return false;
}
size_t written_size = fwrite(content.c_str(), 1, content.length(), fg.getfd());
if (written_size != content.length())
{
CUTL_ERROR("written size is not equal to content size for " + path.str());
return false;
}
int ret = fflush(fg.getfd());
if (0 != ret)
{
CUTL_ERROR("fail to flush file:" + path.str());
return false;
}
if (!file_sync(fg.getfd()))
{
CUTL_ERROR("file_sync failed for " + path.str());
return false;
}
return true;
}
4. 源码地址
更多详细代码,请查看本人写的C++ 通用工具库: common_util, 本项目已开源,代码简洁,且有详细的文档和Demo。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。