是否有任何已实现的 RAII 文件句柄

Is there any RAII file handle already implemented?

本文关键字:RAII 文件句柄 实现 任何 是否      更新时间:2023-10-16

RAII 文件句柄看起来很基本,所以我想它已经实现了?但是我找不到任何实现。我在 boost::iostreams 中找到了file_descriptor,但我不知道这是否是我想要的。

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 ...

取决于你到底想要什么。

如果确实需要作用域句柄,请使用:

std::unique_ptr<HANDLETYPE, closehandletypefunction> smartpointer;

对于FILE指针,这看起来像

std::unique_ptr<FILE, int (*)(FILE *)> f(fopen("myfile.txt", "a"), fclose);

然后可以通过f.get()获得FILE*。同样的事情也适用于文件描述符(分别来自<fcntl.h><unistd.h>openclose)。

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

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

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

但是在再次阅读文档后:

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

所以,这是安全的:)