gpt4 book ai didi

c++ - 如何确定 std::ofstream 打开的文件的当前大小?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:24 29 4
gpt4 key购买 nike

我有一个类,它有一个 ofstream 类型的文件流。构造函数以追加模式打开文件,所有消息始终写入文件末尾。

我需要将 outputFile 写入某个固定大小(比如 1Mb),然后我需要关闭、重命名并压缩它,然后打开一个同名的新文件。

这需要在文件达到一定大小时完成。

我尝试使用 tellg() 但在互联网上阅读资料(和 this )后,我明白这不是正确的方法。

由于我是 C++ 的新手,我正在尝试找出最优化和正确的方法来获取 ofstream 打开的文件的准确当前大小?

class Logger {
std::ofstream outputFile;
int curr_size;
Logger (const std::string logfile) : outputFile(FILENAME,
std::ios::app)
{
curr_size = 0;
}
};

在程序的某处,我正在向其中写入数据:

    // ??? Determine the size of current file ???

if (curr_size >= MAX_FILE_SIZE) {
outputFile.close();
//Code to rename and compress file
// ...
outputFile.open(FILENAME, std::ios::app);
curr_size = 0;
}

outputFile << message << std::endl;
outputFile.flush();

最佳答案

fstreams 可以是输入流和输出流。 tellg()将返回输入位置和 tellp()会告诉你输出位置。 tellp()将在附加到文件后告诉您它的大小。

考虑像这样初始化您的记录器(编辑:为输出流运算符添加示例):

#include <iostream>
#include <fstream>

class Logger {
std::string m_filename;
std::ofstream m_os;
std::ofstream::pos_type m_curr_size;
std::ofstream::pos_type m_max_size;
public:
Logger(const std::string& logfile, std::ofstream::pos_type max_size) :
m_filename(logfile),
m_os(m_filename, std::ios::app),
m_curr_size(m_os.tellp()),
m_max_size(max_size)
{}

template<typename T>
friend Logger& operator<<(Logger&, const T&);
};

template<typename T>
Logger& operator<<(Logger& log, const T& msg) {
log.m_curr_size = (log.m_os << msg << std::flush).tellp();

if(log.m_curr_size>log.m_max_size) {
log.m_os.close();
//rename & compress
log.m_os = std::ofstream(log.m_filename, std::ios::app);
log.m_curr_size = log.m_os.tellp();
}
return log;
}

int main()
{
Logger test("log", 4LL*1024*1024*1024*1024);
test << "hello " << 10 << "\n";
return 0;
}

如果您使用 C++17 或有 <filesystem> 的实验版本可用,您还可以使用它来获取绝对文件大小,如下所示:

#include <iostream>
#include <fstream>
#include <filesystem>

namespace fs = std::filesystem;

class Logger {
fs::directory_entry m_logfile;
std::ofstream m_os;
std::uintmax_t m_max_size;

void rotate_if_needed() {
if(max_size_reached()) {
m_os.close();
//rename & compress
m_os = std::ofstream(m_logfile.path(), std::ios::app);
}
}
public:
Logger(const std::string& logfile, std::uintmax_t max_size) :
m_logfile(logfile),
m_os(m_logfile.path(), std::ios::app),
m_max_size(max_size)
{
// make sure the path is absolute in case the process
// have changed current directory when we need to rotate the log
if(m_logfile.path().is_relative())
m_logfile = fs::directory_entry(fs::absolute(m_logfile.path()));
}

std::uintmax_t size() const { return m_logfile.file_size(); }
bool max_size_reached() const { return size()>m_max_size; }

template<typename T>
friend Logger& operator<<(Logger&, const T&);
};

template<typename T>
Logger& operator<<(Logger& log, const T& msg) {
log.m_os << msg << std::flush;
log.rotate_if_needed();
return log;
}

int main()
{
Logger test("log", 4LL*1024*1024*1024*1024);
std::cout << test.size() << "\n";
test << "hello " << 10 << "\n";
std::cout << test.size() << "\n";
test << "some more " << 3.14159 << "\n";
std::cout << test.size() << "\n";
return 0;
}

关于c++ - 如何确定 std::ofstream 打开的文件的当前大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54237341/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com