Adam Lee
Adam Lee

Reputation: 25768

No exception throw after open a file stream with non-exist files?

I am trying to use

std::ifstream inStream;
inStream.open(file_name);

If file_name does not exists, no exception is thrown. How can I make sure to throw in this case? I am using C++11

Upvotes: 12

Views: 4678

Answers (2)

rustyx
rustyx

Reputation: 85462

Unfortunately setting ios::failbit in the exception mask before calling ifstream::open leads to undesirable results:

  1. The thrown std::ios_base::failure does not state the reason for the I/O failure.
  2. Reaching end-of-file also sets std::ios_base::failbit and hence, also throws an exception.

A possible better solution is to throw std::system_error yourself:

std::ifstream in(file_name);

if (!in.is_open()) {
    throw std::system_error(errno, std::generic_category(), file_name);
}

std::string row;
while (std::getline(in, row)) {
    // . . . process the file . . .
}
if (in.bad()) {
    throw std::system_error(errno, std::generic_category(), file_name);
}

This will give proper error messages explaining the actual I/O error, for example " test.file: No such file or directory"

Upvotes: 3

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

You can do so by setting the streams exception mask, before calling open()

std::ifstream inStream;
inStream.exceptions(std::ifstream::failbit);
try {
    inStream.open(file_name);
}
catch (const std::exception& e) {
    std::ostringstream msg;
    msg << "Opening file '" << file_name 
        << "' failed, it either doesn't exist or is not accessible.";
    throw std::runtime_error(msg.str());
}

By default none of the streams failure conditions leads to exceptions.

Upvotes: 14

Related Questions