views:

2241

answers:

4

I've got a fstream my_file("test.txt"), but I don't know if test.txt exists. In case it exists, I would like to know if I can read it, too. How to do that?

I use Linux.

+3  A: 

What Operating System/platform?

On Linux/Unix/MacOSX, you can use fstat.

On Windows, you can use GetFileAttributes.

Usually, there is no portable way of doing this with standard C/C++ IO functions.

Pablo Santa Cruz
Why do you say that, you could always just try to open a file with fopen and if it returns 0 you can deduce portably that the file is nonexistent.
Blindy
fstat is available on windows, too, in `sys/stat.h`.
xtofl
+12  A: 

I would probably go with:

ifstream my_file("test.txt");
if (my_file.good())
{
  // read away
}

The good method checks if the stream is ready to be read from.

Kim Gräsman
xtofl
Yeah, that's true. I read the OP's question that the file was already opened anyway, but I could be wrong.
Kim Gräsman
+3  A: 

if you are on unix then access() can tell you if it's readable. However if ACL's are in use, then it gets more complicated, in this case it's best to just open the file with ifstream and try read.. if you cannot read then the ACL may prohibit reading.

neoneye
access() is a great way to introduce time-of-check-to-time-of-use bugs.
bk1e
Awesome! Thanks a bunch - I was poking around for a C (not C++) solution, and this looks perfect.
rampion
+5  A: 

You might use Boost.Filesystem. It has a boost::filesystem::exist function.

I don't know how about checking read access rights. You could look in Boost.Filesystem too. However likely there will be no other (portable) way then try to actually read the file.

Adam Badura
Does boost filesystem handle very long paths on windows (> 256)? We recently ran into the problem that the non unicode windows API has a maximum of 256 characters.
Richard Corden
I don't know. You might check in documentation (at the link in my answer) but I'm not sure whether you will find it and its long. You might also ask on Boost news group. Another way is to simply check it.
Adam Badura
@Richard Corden I checked very long paths with function boost::filesystem::create_directories. ANSI version (for char) threw an exception if given to long path (but the limit was somehow reached around 250 rather then MAX_PATH which is equal to 260). UNICODE version (for wchar_t) created as much folders as ANSI version would without throwing and returned successfully so not only it did not do the job but also it did not report the error. I don't know how is it with other functions but I suspect now they might behave badly as well.
Adam Badura