Re: fopen - file and directories ??
On Oct 10, 8:33 pm, "Ross A. Finlayson" <ross.finlay...@gmail.com>
wrote:
On Oct 5, 1:59 am, "fdm" <f...@gk.com> wrote:
I use fopen to check if a file or directory exists:
#include <stdio.h>
#include <string>
void file_exists(std::string file) {
FILE* fp = NULL;
fp = fopen( file.c_str(), "rb" );
if( fp == NULL ) {
std::cout << "File = " << file << " does not exist!" << std::endl;
exit(0);
}
fclose(fp);
}
On Ubuntu linux this works fine both for files and
directories. But on windows vista 64 using visual studio
2008 it only works for files. If 'file' is eg:
"c:\test" // I have also tried with ''c:/test"
then I get the message:
File = c:/test/ does not exist!
which means that fp is NULL. Why does it work on linux for
directories but not on windows?
Because in Linux or Unix the directories are actually files.
That was more or less true in early Unix (but you couldn't open
them for writting). But it's certainly not true in Linux or
Unix today---like most systems, Linux and Unix support different
file systems, and whether you can open a directory like you open
a file depends on the file system, not the OS. Under most Unix
today, for example, this will work for a local file, but it
fails for an NFS mounted file (and probably for an SMB mounted
file as well, but I've never tried it). Basically, it's not
reliable anywhere.
On Windows there's a DOS file attribute or so, the file system
attribute.
Yes, but at least for the old DOS file systems, directories were
as much files as they were under early Unix. It is simply a
choice of the system authors that the standard open call would
fail if the "file" had a directory type.
So you can't open directories with fopen on Windows. On
Windows, getting the directory is null, because as a file it's
null. (I could be wrong, also it could be set up to return an
open file handle if you use your own API routines around the
Windows API.) On Unix, getting the directory is a file, with
a list of the files in the directory.
If you successfully open a local directory, you still don't have
just a list of files. You have some sort of structured
data---it was definitely different between version 7 and Berkley
4.2, for example.
On some Unix machines the directories have user and group
attributes so the directory access could be made null on Unix
also.
On all Unix machines, directories (and anything else that can be
found in the file system---named pipes, etc.) always have user,
group and global access rights. Whether they really mean
anything for remotely mounted files is harder to say---with NFS
running on a Unix based server, they certainly do, but I'd be
less sure for SMB running on a Windows machine. (SMB, on the
other hand, supports the Windows access control scheme, which is
a lot more sophisticated than what Unix provides.)
In C++ it's called ::fopen(const char*, ...);, let's see, the
second argument to fopen is the collected open flags so it
could be a byte, probably it is a default numeric type the
integer: int.
Whether it's called ::fopen or std::fopen depends on whether you
included <stdio.h> or <cstdio>. And the second argument is a
string (C style, of course, since it's a function inherited from
the C library).
fopen(const char*, const char*);
Why it's ::fopen instead of fopen() is that then other C++
programs in the same code could use fopen instead of ::fopen.
In C++ it's standard that ::fopen() is the same as fopen().
No. In C++ ::fopen is the function declared in the global
namespace (in <stdio.h>), std::fopen is the one declared in std
(in <cstdio>), and fopen, without any qualification, is
whichever one the compiler happens to find (and thus might be a
user defined function, totally unrelated to the standard fopen).
--
James Kanze