是否已经实现了RAII文件句柄?

时间:2014-04-01 02:04:22

标签: c++ io raii

RAII文件句柄看起来非常基本,所以我猜它已经实现了?但我找不到任何实施方案。我在boost :: iostreams中找到了file_descriptor,但我不知道它是不是我正在寻找的东西。

3 个答案:

答案 0 :(得分:6)

std::fstream支持RAII风格的使用 - 它们可以在构造时打开甚至测试,并且它们会在析构函数中自动刷新和关闭,但如果你只是假设有效,它们可能会错过错误所以如果你需要健壮性,你可能想在代码中做一些更明确的事情。

例如:

if (std::ifstream input(filename))
    ... use input...
else
    std::cerr << "unable to open '" << filename << "'\n";

如果你真的想使用文件描述符,你可以调整类似下面的东西来品尝。它只比调用close的东西长一点,但是如果你想进行强大的编程,你需要以某种方式检查和处理错误....

struct Descriptor
{
    Descriptor(int fd, const char* filename = nullptr)
      : fd_(fd), filename_(filename)
    {
        if (fd < 0)
        {
            std::ostringstream oss;
            oss << "failed to open file";
            if (filename_) oss << " '" << filename_ << '\'';
            oss << ": " << strerror(errno);
            throw std::runtime_error(oss.str());
        }
    }
    ~Descriptor()
    {
        if (fd_ != -1 && close(fd_) == -1)
        {
            // throwing from destructors risks termination - avoid...
            std::cerr << "failed to close file";
            if (filename_) std::cerr << " '" << filename_ << '\'';
            std::cerr << ": " << strerror(errno) << std::endl;
        }
    }
    operator int() const { return fd_; }

  private:
    int fd_;
};

用法:

try
{
    Descriptor fd(open(filename, O_RDONLY), filename);
    int nbytes = read(fd, ...);
    ...
}
catch ...

答案 1 :(得分:2)

我正在使用boost::filesystem::ifstream(或ofstream写作)。

我实际上是在问这个问题因为我想确保我的文件已关闭,即使在调用file.close()之前引发了异常

但在再次阅读文档之后:

  

如果对象在与打开的文件关联时被销毁,则析构函数会自动调用成员函数close。

所以,这是安全的:)

答案 2 :(得分:1)

取决于你想要什么。

如果您真的想要一个范围句柄,请使用:

std::unique_pointer<HANDLETYPE, closehandletypefunction> smartpointer;

首选的C ++方法是将句柄包装在一个拥有数千个成员的对象中,以完成所有操作。