使用ios_base :: register_callback()和ios_base :: event来检测流关闭

时间:2014-08-08 03:56:13

标签: c++ callback stream

我有一个向API用户返回unique_ptr<ofstream>的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

1 个答案:

答案 0 :(得分:0)

您可以将ios::event参数与erase_event进行比较,以检测流销毁情况。为防止复制erase_event处理程序,您可以在copyfmt_event上将其教导为中性。

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

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