gpt4 book ai didi

c++ - 使用 ios_base::register_callback() 和 ios_base::event 检测流关闭

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:22:55 25 4
gpt4 key购买 nike

我有一个返回 unique_ptr<ofstream> 的 API给 API 用户。我想知道用户何时完成此流,以便我可以对他们刚刚写入的文件采取进一步的操作。必须关闭该文件,因为即将重新挂载分区。

这可能是这个问题的错误解决方案,但就在我返回流之前,我用 register_callback() 注册了一个回调。 :

std::unique_ptr<std::ofstream> os(new std::ofstream(name, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary));
os->register_callback(done_callback, 0);
return os;

回调在别处定义:

void done_callback(std::ios_base::event evt, std::ios_base& str, int idx)
{
// Do something when the file closes ... and only then.
}

现在,ios_base::event告诉回调一些刚刚发生的事情。一个事件是 erase_event ,而这个事件的触发器之一是流对象的销毁。这对我有用。我担心触发回调的其他条件 - copyfmt() .

  • 我应该担心这个还是相信没有人会导致 copyfmt()被称为?
  • 有没有更好的方法来完成我的目标?

这是我用来测试它的源代码(完整、剪切/粘贴),然后是该程序的输出:

#include <iostream>
#include <fstream>
#include <memory>

void done_callback(std::ios_base::event evt, std::ios_base& str, int idx)
{
std::cout << "Some sort of stream event occurred. Event: " << evt << std::endl;
}

int main(int argc, char* argv[]) {
std::cout << "Opening the stream." << std::endl;
std::unique_ptr<std::ofstream> os(new std::ofstream("test", std::ofstream::out | std::ofstream::trunc | std::ofstream::binary));
std::cout << "Stream is open." << std::endl;

std::cout << "Registering callback." << std::endl;
os->register_callback(done_callback, 0);

std::cout << "Writing to stream." << std::endl;
*(os.get()) << "Hello!\n";
std::cout << "Done writing." << std::endl;

std::cout << "Flushing stream." << std::endl;
os->flush();
std::cout << "Done flushing." << std::endl;

std::cout << "Writing to stream." << std::endl;
*(os.get()) << "Hello!\n";
std::cout << "Done writing." << std::endl;

std::cout << "Closing the stream..." << std::endl;
os->close();
std::cout << "Stream is closed." << std::endl;
}

输出:

Opening the stream.
Stream is open.
Registering callback.
Writing to stream.
Done writing.
Flushing stream.
Done flushing.
Writing to stream.
Done writing.
Closing the stream...
Stream is closed.
Some sort of stream event occurred. Event: 0

最佳答案

您可以将 ios::event 参数与 erase_event 进行比较以检测流破坏。为防止复制 erase_event 处理程序,您可以教它在 copyfmt_event 时 self 中性化。

但是,这不是管理文件的好方法。 (关于安全文件管理的任何事情对于分区来说都是双倍的。) fstream 对象不是保持文件打开的对象,filebuf 是。标准流对象只处理格式化; stream buffer 对象处理 I/O。

幸运的是,streambuf 有一个 virtual destructor ,因此您可以从 std::filebuf 派生并在那里添加一些功能。不幸的是,析构函数应该始终是故障安全的,因此它不是挂载文件系统的好地方。您应该只在应用程序的待办事项列表中排队挂载操作。

关于c++ - 使用 ios_base::register_callback() 和 ios_base::event 检测流关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25195828/

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