RAII 文件句柄看起来非常基本,所以我猜它已经被实现了?但我找不到任何实现。我在 boost::iostreams 中找到了 file_descriptor 但我不知道这是否是我要找的。
std::fstream
支持 RAII 风格的用法 - 它们可以在构造时打开甚至测试,并且它们会在析构函数中自动刷新和关闭,尽管如果您只是假设它有效,您可能会错过错误,所以您可能想要这样做如果您需要鲁棒性,请在代码中使用更明确的内容。
例如:
if (std::ifstream input(filename))
... use input...
else
std::cerr << "unable to open '" << filename << "'\n";
如果您确实想使用文件描述符,您可以调整如下内容来品尝。它比仅仅调用
close
的东西要长一点,但是如果你想做健壮的编程,你需要以某种方式检查和处理错误......
#include <iostream>
#include <iomanip>
#include <string>
#include <exception>
#include <sstream>
#include <cstring> // for strerror
#include <unistd.h> // for close
struct Descriptor
{
Descriptor(const Descriptor&) = delete;
Descriptor(Descriptor&&) = default;
Descriptor(int fd, std::string filename = "")
: fd_{fd}, filename_{std::move(filename)}
{
if (fd < 0)
{
std::ostringstream oss;
throw std::runtime_error(err(oss, "open").str());
}
}
~Descriptor()
{
if (fd_ != -1 && close(fd_) == -1)
// destructor throw risks termination; avoid
err(std::cerr, "close") << '\n';
}
operator int() const { return fd_; }
private:
int fd_;
std::string filename_;
auto err(auto& os, const char* operation) const -> decltype(os) {
os << "failed to " << operation << " file";
if (!filename_.empty())
os << ' ' << std::quoted(filename_);
os << ": " << strerror(errno);
return os;
}
};
#include <fcntl.h>
int main()
try
{
const char* filename = "/proc/cmdline";
Descriptor fd(open(filename, O_RDONLY), filename);
char buffer[1024];
std::cout.write(buffer, read(fd, buffer, sizeof buffer)); // TODO error handling
}
catch (const std::exception& e)
{
std::cerr << e.what() << '\n';
}
取决于你到底想要什么。
如果您确实想要一个作用域句柄,请使用:
std::unique_ptr<HANDLETYPE, closehandletypefunction> smartpointer;
对于
FILE
指针,这看起来像
std::unique_ptr<FILE, int (*)(FILE *)> f(fopen("myfile.txt", "a"), fclose);
然后可以用
FILE*
获得 f.get()
。同样的事情也适用于文件描述符(分别来自 open
和 close
的 <fcntl.h>
和 <unistd.h>
)。
首选的 C++ 方法是将句柄包装在具有数千个成员的对象中以完成所有操作。
我正在使用
boost::filesystem::ifstream
(或 ofstream
进行书写)。
我实际上问这个问题是因为我想确保即使在调用之前引发异常,我的文件也已关闭
file.close()
但是再次阅读文档后:
如果对象在仍与打开的文件关联时被销毁,则析构函数会自动调用成员函数 close。
所以,这是安全的:)