How to check if a file exists and is readable in C++?

C++LinuxFileFstreamExists

C++ Problem Overview


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.

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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 than try to actually read the file.

EDIT (2021-08-26): C++17 introduced <filesystem> and there you have std::filesystem::exists. Boost is no longer needed for this.

Solution 3 - C++

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.

Solution 4 - C++

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.

Solution 5 - C++

C++17, cross-platform: Check file existence with std::filesystem::exists and readability with std::filesystem::status & std::filesystem::perms:

#include <iostream>
#include <filesystem> // C++17
namespace fs = std::filesystem;

/*!	\return	True if owner, group and others have read permission,
			i.e. at least 0444.
*/
bool IsReadable(const fs::path& p)
{
	std::error_code ec; // For noexcept overload usage.
	auto perms = fs::status(p, ec).permissions();
	if ((perms & fs::perms::owner_read) != fs::perms::none &&
		(perms & fs::perms::group_read) != fs::perms::none &&
		(perms & fs::perms::others_read) != fs::perms::none
		)
	{
		return true;
	}
	return false;
}

int main()
{
	fs::path filePath("path/to/test.txt");
	std::error_code ec; // For noexcept overload usage.
	if (fs::exists(filePath, ec) && !ec)
	{
		if (IsReadable(filePath))
		{
			std::cout << filePath << " exists and is readable.";
		}
	}
}

Consider also checking for the file type.

Solution 6 - C++

Since C++11 it's possible to use implicit operator bool instead of good():

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

Solution 7 - C++

I know the poster eventually said they were using Linux, but I'm kind of surprised that no one mentioned the PathFileExists() API call for Windows.

You will need to include the Shlwapi.lib library, and Shlwapi.h header file.

#pragma comment(lib, "shlwapi.lib")
#include <shlwapi.h>

the function returns a BOOL value and can be called like so:

if( PathFileExists("C:\\path\\to\\your\\file.ext") )
{
    // do something
}

Solution 8 - C++

Concerning the use of fstat in windows, I am not sure if it is what you want. From Microsoft the file must be already open. Stat should work for you.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJerryView Question on Stackoverflow
Solution 1 - C++Kim GräsmanView Answer on Stackoverflow
Solution 2 - C++Adam BaduraView Answer on Stackoverflow
Solution 3 - C++neoneyeView Answer on Stackoverflow
Solution 4 - C++Pablo Santa CruzView Answer on Stackoverflow
Solution 5 - C++Roi DantonView Answer on Stackoverflow
Solution 6 - C++VadzimView Answer on Stackoverflow
Solution 7 - C++Drew ChapinView Answer on Stackoverflow
Solution 8 - C++AntoniView Answer on Stackoverflow