I would like to check if the string name
refers to a file that I can open and read from, so it can be a regular file or a symlink.
I first used this:
std::ifstream in(name.c_str());
if (!in.is_open()) {
// throw exception!
}
but it didn't throw an exception when name
referred to a directory name.
Now I'm using this:
if (!fs::exists(name) || fs::is_directory(name)) {
// throw exception!
}
But it will (presumably) not throw if it's a symlink to a directory. The same is true for this:
if (!fs::is_regular_file(name) && !fs::is_symlink(name)) {
// throw exception!
}
Is there a better way?
As of Boost.Filesystem v3, checking if it is a regular file already does what you want. The following is a simple code:
#include <boost/filesystem.hpp>
#include <iostream>
namespace fs = boost::filesystem;
int main(int argc, char* argv[]) {
if (argc > 1) {
auto status = fs::status(argv[1]);
if (status.type() == fs::regular_file)
std::cout << argv[1] << " is a valid path." << std::endl;
else
std::cout << argv[1] << " is not a valid path." << std::endl;
if (fs::symlink_status(argv[1]).type() == fs::symlink_file)
std::cout << "It is also a symlink." << std::endl;
} else {
std::cerr << "A path must be given." << std::endl;
}
return 0;
}
Here are some outputs:
% ./fstest /bin # it is a symlink path
/bin is not a valid path.
It is also a symlink.
% ./fstest /bin/ # it is a symlink path but dereferenced? (trailing /)
/bin/ is not a valid path.
% ./fstest /bin/zsoelim # it is a symlink
/bin/zsoelim is a valid path.
It is also a symlink.
% ./fstest /bin/soelim # it is not a symlink
/bin/soelim is a valid path.
So as you can see, boost::filesystem::status(path)
returns the information about the actual path whether it is a symlink (followed to the real location) or not. On the other hand, boost::filesystem::symlink_status(path)
returns the information if the file itself is symlink or not.
More information can be found on boost docs.
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