How do i check if a file exists using ANSI C++?
kentl

Hi!

How do i check if a file exist using ANSI C++ functionality? I would like to be able to check for the file in the same way both on *NIX systems and Windows. The file is a binary file. (And preferably using the ANSI C++ way) ::)

Many thanks in advance! ;D

Ceniza

This is an ANSI/ISO C++ method:

#include <fstream>

inline bool FileExists(const char * filename)
{
  return std::ifstream(filename);
}

If you need a strict ANSI C++ method, adding .h to fstream in the #include and removing std:: in ifstream should be enough (I'm not really used to just ANSI C++).

(If it can't be opened for reading it's surely because the file doesn't exist)

That code won't create it neither, so it's safe in that sense and the file will get closed when leaving the function.

MiquelFire

What if the file can't be read by your program?

gillius

Then it won't be detected as existing. But it is very rare for a file to be visible to you but for you not to have at least read-only priviledges on it. There isn't a better ISO standard way I can think of to detect file existing -- you will have to use OS-specific functions if you want something "better".

One could make the case that if you could not read a file then it might as well not exist to you. Unless of course you have create new files permissions but not overwrite or read. Then if you really want to detect this case, you'll probably be trying to create a file anyway, so you'll get an error if the file already exists and you can't overwrite it.

Marco Radaelli

I think that this case is possible:
an app is reading / writing from / to a file (that stream is open). Now you can't open another stream on that file. The file exists but can't be detected by your function. Isn't that right?

gillius

Depending on the OS you might be able to do multiple read, but in Windows you CAN lock people out using Windows-specific APIs. You can probably do it on Linux too but it's not as common.

Like I said, that's the best you can do with standard ISO C++. He needs to use OS functions if he wants better.

kentl

Thanks for all the answers! I got it working now using "std::ifstream(filename);".

One last question though, a filestream is created using the above. Shouldn´t it be fetched and closed to be reeealy correct? (i am a real c++ newbie as you can see) ;D

Ceniza
kentl said:

Shouldn´t it be fetched and closed to be reeealy correct?

The way that function works is this:

  • Receives the file name in filename. (It's the most obvious part.)

  • Creates a temporary std::ifstream object that tries to open that file with its default open mode (read).

  • Because the function returns bool, then it tries to cast from std::ifstream to bool and std::ifstream provides such cast that tells you if the file is opened or not.

  • Such value is returned and the temporary object is destroyed (when this object is destroyed, it closes the file.)

guilt

If ya want, add something like :

bool fexflag = false;
ifstream aif = new ifstream(filename);
if(aif) {fexflag=true;aif.close();}
return fexflag;

Ok... I didn't see that one coming ...

[edit]
Guyz .. you can't do a new ifstream(filename) ....
and then delete it ....
so ... i guess this is OK :

ifstream aif;
aif.open(filename);
...

[/edit]

gillius

That leaks memory Guilt. Do the first given function. It is the best quality, clearest, and safest function.

Evert
Quote:

The file is a binary file

There's no real distinction between binary files and text files. A file is a file from the OS point of view ;)

Anyway, there are no ANSI (or rather, ISO) solutions for reading the contents of a directory, or checking for the existence of a file.
You could use Allegro's exists() function (or maybe it's called file_exists(), check the docs) if you aren't worried about being committed to Allegro. My recommendation would be to use the POSIX functions opendir(), readdir(), stat() and friends. They aren't that difficult to use, portable (POSIX functionality is available on all UNIX systems, Linux, DOS (through DJGPP) and Windows (through MinGW and Cygwin)) and give you everything you need. The API is C though, so you may want to write a C++ wrapper if a C++ interface is what you want. This shouldn't be too difficult.

guilt

Hey Gillius,

I really don't think that there is a memory leak
problem ...

The scope of the variable is local (though inline).

All instances of the local variable
are automatically deallocated at the end of the program.

Besides, People,

Whenever you use the functions fopen / open etc, it needn't be that
they return the right result. There is also
a limit on the number of Open files at a point of Time (in DOS...)
And a file can't be opened in rw mode if it's read-only.

So, it is better really to use lower level functions that
handle with the OS.

maybe stat() is one such thing. Or
try to get the status of a dir system command ...

There are reommended possible ways of doing the file checking.

Ceniza
guilt said:

bool fexflag = false;
ifstream aif = new ifstream(filename);
if(aif) {fexflag=true;aif.close();}
return fexflag;

guilt said:

I really don't think that there is a memory leak problem ...

Lemme see...

bool fexflag declared and initialized with false, automatically "freed" when it get out of scope.

ifstream aif initialized with an <b>ifstream value created with operator new. aif will be automatically "freed" when it get out of scope. Assignment from incompatible type and the memory allocated with operator new has to be deallocated with operator delete or you'll get a funny memory leak.

If aif is opened, assign true to fexflag and close aif.

Return the value of fexflag.

Operator delete wasn't called so... memory leak! \o/

BTW... what's that null.txt file you attached for?

Mae Mutts

See Guilt's null text file reason over the allegro.cc comments forum

http://www.allegro.cc/forums/view_thread.php?_id=314013&request=1068643434&

guilt

Ceniza ...

Incompatible compiler types, huh ...? that thing is a Compiler Error!

;)

Ceniza

Yeah, compile error, but what Gillius must have been meaning with the memory leak part is about new: you aren't calling delete before returning.

guilt said:

[edit]
Guyz .. you can't do a new ifstream(filename) ....
and then delete it ....
so ... i guess this is OK :

ifstream aif;
aif.open(filename);
...

[/edit]

Uh? You can even do:

delete new std::ifstream(filename);

Dunno, maybe you got confused with Java's method to deal with objects.

I must also add that new std::ifstream(filename); won't fail if the file cannot be opened, it will only fail if there's not enough memory for creating the object, or if the object's constructor throws an exception. If the file cannnot be opened thru std::ifstream, it won't throw.

guilt

That's coz i don't need to ...
:D

Quote:

See ... No Pointers ..!!

Thread #313562. Printed from Allegro.cc