A RAII file handle looks pretty basic so I guess it has already been implemented? But I couldn't find any implementation. I found file_descriptor in boost::iostreams but I don't know if it's what I'm looking for.
std::fstream
s support RAII-style usage - they can be opened and even tested at construction, and they're automatically flushed and closed in the destructor, though you could miss errors if you just assume that works so you may want to do something more explicit in code if you need the robustness.
For example:
if (std::ifstream input(filename))
... use input...
else
std::cerr << "unable to open '" << filename << "'\n";
If you really want to use file descriptors, you can tune something like the following to taste. It's a bit longer than something that just invokes close
, but if you want to do robust programming you need to check for and handle errors somehow....
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_;
};
Usage:
try
{
Descriptor fd(open(filename, O_RDONLY), filename);
int nbytes = read(fd, ...);
...
}
catch ...
Depends on what exactly you want.
If you really want a scoped handle, use:
std::unique_ptr<HANDLETYPE, closehandletypefunction> smartpointer;
For FILE
pointers, this would look like
std::unique_ptr<FILE, int (*)(FILE *)> f(fopen("myfile.txt", "a"), fclose);
The FILE*
can then be gotten with f.get()
. The same thing would work with file descriptors (open
and close
from <fcntl.h>
and <unistd.h>
, respectively).
The preferred C++ way is wrapping the handle in an object with thousands of members to do everything though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With