How to check if a file exist or not

Hello,

On the very end of my program, I have a code to close a temporary file("destinationFile.txt"), delete the present "OutputFile.txt" and then rename the temporary file "OutputFile.txt".

Everything works OK as long as the original "OutputFile.txt" is present to be erased. If the "OutputFile.txt" is absent and my program says Remove, my program exits gently, at least it does not crash.

Is there, 1 or 2 statement that I could use so I can check if the file is present before I do a Remove if needed? a portion of the code is down below for your perusal?

Thanks,
Ed Mendoza



MyDestinationFile.close();
//delete the test file
if (remove(REVERSEWORDFILE) == -1)
{
cout << cerr << "Renaming the file " << REVERSEWORDFILE << "failed";
exit(EXIT_FAILURE);
}
//rename the Temporary file by the Test File, this will make it look like
//we did a direct modification of the test file
if (rename(TMP_FILE, REVERSEWORDFILE) == -1)
{
cout << cerr << "Renaming the file " << TMP_FILE << "failed";
exit(EXIT_FAILURE);
}
return(funcCurrentSeparator);
Last edited on
closed account (N36fSL3A)
Use code tags...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MyDestinationFile.close(); 
//delete the test file
if (remove(REVERSEWORDFILE) == -1)
{
	cout << cerr << "Renaming the file " << REVERSEWORDFILE << "failed";
	exit(EXIT_FAILURE);
}
//rename the Temporary file by the Test File, this will make it look like 
//we did a direct modification of the test file
if (rename(TMP_FILE, REVERSEWORDFILE) == -1)
{
	cout << cerr << "Renaming the file " << TMP_FILE << "failed";
	exit(EXIT_FAILURE);
} 
return(funcCurrentSeparator);


EDIT - I added indentation, sorry if they are large, since I am not home all I have to work with is Notepad tabs.
Last edited on by Fredbill30
Use fopen ("filename", "rb") and check if the return value is NULL. Don't forget to fclose () if the return value is a valid FILE pointer.

You could use a more platform specific function like CreateFile() in windows which you can tell if the file really exists, but it is used by another process.
But you don't need that.... you could just call rename()

Also, cout << cerr ¿eh?
To ne555: I tried just the rename section and no remove section, but when the file is not there RENAME considers that also an error and my program do an exit(EXIT_FAILURE) which is a part of the code in order to have a gentle exit.

Fredbill30: I know it is not readable when not properly indented, but I did a cut and paste and from the Visual Studio editor it was properly indented. why this editor ignored the tabs when I pasted it, I do not have any idea.

modoran: I can do this, open the file check the return value if it is NULLand then close the file. However, what is my guaranty that the NULL return was only because the file is not there. There could be hundred of reasons to return a NULL. I want fool proof. But your is the most logical solution so far.
I did this for now to get around it. But, my professor does not like codes that overrides error conditions. When you get an error he wants you to exit but exit gently, he does not want the program to crash.

if (remove(REVERSEWORDFILE) == -1)
{
cout << cerr << " RENAMING THE FILE " << REVERSEWORDFILE << " FAILED \n";
cout << " FILE IS NOT AVAILABLE FOR REMOVAL: PRESS 0, RETURN TO IGNORE MESSAGE ";
cout << " PRESS 1, RETURN TO IGNORE EXIT \n";
cin >> ignoreErrorMessage;
if(ignoreErrorMessage)
exit(EXIT_FAILURE);
}

Why should you exit at all if the original file isn't there? You're deleting it anyway so shouldn't it just output some text then go about it's business? Unless this is a way to practice error handling in which case never mind.
modoran: I can do this, open the file check the return value if it is NULLand then close the file. However, what is my guaranty that the NULL return was only because the file is not there. There could be hundred of reasons to return a NULL. I want fool proof. But your is the most logical solution so far.


That's why I say to use operating system APIs to determine exact cause of the error (I think only bullet proof solution is try to open the file for exclusive access, eliminating a possible race condition if another process deletes/creates the file exactly after you check file existence, but exactly before you proceed with your program logic).
I'm with Computergeek01. If the file doesn't exist, the error is not really an error.

But if you want to play safe, when remove() fails you could check errno to see what it's been set to. If it's ENOENT (error no entity -- ie couldn't find the file) then you can ignore the error. (ENOENT and the other error codes should be found in errno.h)

Also, while fopen/fclose is a good way to go if you want to stick to pure-C or C++, if you're coding with the Win32 API, you should use the stock function PathFileExists() (defined in Shlwapi.h) *Unless* you need to ensure you have exclusive access before you delete it, which requires CreateFile.

Andy

remove()
http://www.cplusplus.com/reference/clibrary/cstdio/remove/

perror() -- to print a description of the error
http://www.cplusplus.com/reference/clibrary/cstdio/perror/

PathFileExists function
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773584%28v=vs.85%29.aspx
Last edited on
This functionality is beyond what the standard library offers. If you want the fullproof way to do this, you'll need to use either the platform SDK (WinAPI if on Windows), or some kind of crossplatform filesystem library (like boost).


To do this in WinAPI, the function you want is FindFirstFile (or FindFirstFileA if you want to use ASCII strigs / char arrays):

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
WIN32_FIND_DATAA info;  // note:  DATAA, not DATA .. that isn't a typo

HANDLE handle = FindFirstFileA( "targetfilename.txt", &info );

if( handle != INVALID_HANDLE_VALUE )
{
  // here, we know that "targetfilename.txt" exists.
  //  'info' contains information about it, such as whether it's hidden, a system file, a directory
  //  the modifed date/time, etc


  // do this to clean up:
  FindClose( handle );
}
else
{
  // here, we know that "targetfilename.txt" does not exist
  //  no need to clean anything up
}


EDIT: ninja'd by andywestkin -- who recommended PathFileExists which is probably more straightforward than my FindFirstFile approach (didn't know about that function!). I'd go with that route instead.
Last edited on
closed account (N36fSL3A)
@mendozae

Alright, but when you use code tags, the webiste will post the tabs. Without, it will not.
but when the file is not there RENAME considers that also an error
That shouldn't happen, ¿what does perror() say?

(fopen) However, what is my guaranty that the NULL return was only because the file is not there.
errno will tell why returned NULL.

For completeness access(filename, F_OK); //unistd.h
i havent read the whole thread but why not just use good() bad() or fail()?
@ Aramil: because fstream can fail for reasons other than the file not existing.
Topic archived. No new replies allowed.