Discussion:
Quickest way to detect whether a file exists?
(too old to reply)
unknown
2004-09-29 18:01:46 UTC
Permalink
Normally I use CreateFile to detect whether a file exits via checking
INVALID_HANDLE_VALUE state.
Is this the quickest way to confirm file existence ?


Any sugestion ?


Thanks,


Mike
William DePalo [MVP VC++]
2004-09-29 18:18:15 UTC
Permalink
Post by unknown
Normally I use CreateFile to detect whether a file exits via checking
INVALID_HANDLE_VALUE state.
Is this the quickest way to confirm file existence ?
I doubt it. In any case I don't think it is optimal in many cases - suppose
for example that the file is already opened for exclusive access.

The documented way to scan a directory is to use
FindFirstFile()/FindNextFile()/FindClose(). You can also try
GetFileAttributes(). If it succeeds the file is present, if not check the
last error code for more info. The C runtime (for which you may have source)
includes _access() which fails with ENOENT if the filel doesn't exist.
Post by unknown
Any sugestion ?
I think you may want to try a few things -creating a file, scanning a
directory, getting attributes etc, using the runtime - and determine
empirically what works best for you if performance is critical.

Regards,
Will
qfel
2004-09-29 18:53:49 UTC
Permalink
I guess CreateFile is faster because for FindFirstFile you have to check
found file name (AFAIR FindFirstFile can return "file1234" for pattern
"file1").
Just pass all share access and no rights to CreateFile;
Also, you should check if file opening successes, file can get deleted after
you had checked for its existence, so what's the point?
Jochen Kalmbach
2004-09-29 19:04:08 UTC
Permalink
Post by qfel
I guess CreateFile is faster because for FindFirstFile you have to
check found file name (AFAIR FindFirstFile can return "file1234" for
pattern "file1").
CreateFile has one big side-effect: It changes the last access time!

It might be faster than FindFirstFile, but the fastest (and the function
which is used by _access) and better function is:

GetFileAttributes
http://msdn.microsoft.com/library/en-us/fileio/base/getfileattributes.asp

And even faster is to use the GetFileAttributesW-function (because no
conversion from ANSI to UNICODE have to be done).

Internally it calls "NtQueryAttributesFile"

Just from the "undocumented documentation":
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%
20Objects/File/NtQueryAttributesFile.html

<quote>
Use of NtQueryAttributesFile is the easiest and the best way to check if
file exist. NtOpenFile isn't good for this, becouse it modifies last access
time for opened file. See NtQueryDirectoryFile for details.
</quote>
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Gary Chanson
2004-09-29 19:24:43 UTC
Permalink
Post by Jochen Kalmbach
Post by qfel
I guess CreateFile is faster because for FindFirstFile you have to
check found file name (AFAIR FindFirstFile can return "file1234" for
pattern "file1").
CreateFile has one big side-effect: It changes the last access time!
No it doesn't, unless you actually read from the file. Just opening it
for read does not change the access stamp.
--
-GJC [MS Windows SDK MVP]
-Software Consultant (Embedded systems and Real Time Controls)
- http://www.mvps.org/ArcaneIncantations/consulting.htm
-***@mvps.org
unknown
2004-09-29 22:03:25 UTC
Permalink
Thanks for all the replies.
I will try all the methods supplied. Probably I will not use
FindFirstFile()/... that will go through all the files in the folder.


Mike,
William DePalo [MVP VC++]
2004-09-30 00:42:57 UTC
Permalink
Post by unknown
Thanks for all the replies.
I will try all the methods supplied. Probably I will not use
FindFirstFile()/... that will go through all the files in the folder.
If you use a wildcard pattern like "*.*" it will match everything. If you
just want to check for the presence of a file you would use its name. Still,
you'd have to call the functions more than the one time required by
GetFileAttributes().

Regards,
Will
Gary Chanson
2004-09-29 19:21:38 UTC
Permalink
Post by qfel
I guess CreateFile is faster because for FindFirstFile you have to check
found file name (AFAIR FindFirstFile can return "file1234" for pattern
"file1").
No. It will return "file.xyz123" for the pattern "file.xyz" though.
--
-GJC [MS Windows SDK MVP]
-Software Consultant (Embedded systems and Real Time Controls)
- http://www.mvps.org/ArcaneIncantations/consulting.htm
-***@mvps.org
Stefan Kuhr
2004-10-15 11:27:46 UTC
Permalink
Hello everyone,
Post by qfel
I guess CreateFile is faster because for FindFirstFile you have to check
found file name (AFAIR FindFirstFile can return "file1234" for pattern
"file1").
Just pass all share access and no rights to CreateFile;
Also, you should check if file opening successes, file can get deleted after
you had checked for its existence, so what's the point?
Does anyone have reliable figures or the right answer to a similar
question: What is the fastest way to determine the size of a file via
GetFileSize? Passing a handle from FindFirstFile or passing a handle
from CreateFile? A peer of mine claims that passing a handle from
FindFirstFile was an order of magnitude faster in her tests than using
CreateFile. Does FindFirstFile call CreateFile under the hood or is a
completely different implementation employed for FindFirstFile instead?


The two implementations (for files<4GB) of hers are the following:

BOOL FileGetSize(LPCTSTR lpszFileName, DWORD& dwSize)
{
WIN32_FIND_DATA FD;

HANDLE hFindFile = FindFirstFile ( lpszFileName, &FD );
if (hFindFile == INVALID_HANDLE_VALUE)
return FALSE;

FindClose (hFindFile);
// dont return Directories
if (FD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
return FALSE;

dwSize = FD.nFileSizeLow;
return TRUE;
}

BOOL FileGetSize2(LPCTSTR lpszFileName, DWORD& dwSize)
{
HANDLE hFindFile = CreateFile(lpszFileName, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

if (hFindFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}

dwSize = GetFileSize(hFindFile, 0);
CloseHandle(hFindFile);
return TRUE;
}




Comments anyone?
--
Stefan Kuhr

"Lesen schadet der Dummheit"
Jochen Kalmbach
2004-10-15 11:35:48 UTC
Permalink
Post by Stefan Kuhr
What is the fastest way to determine the size of a file via
GetFileSize? Passing a handle from FindFirstFile or passing a handle
from CreateFile?
Opening a file is always more time consuming than just querying the meta
data...

So I suggest to use FindFirstFile.
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Sigurd Stenersen
2004-09-29 19:44:14 UTC
Permalink
Post by unknown
Normally I use CreateFile to detect whether a file exits via checking
INVALID_HANDLE_VALUE state.
Is this the quickest way to confirm file existence ?
Any sugestion ?
_access()
--
Sigurd
http://utvikling.com
Doron Holan [MS]
2004-10-06 05:42:24 UTC
Permalink
the bigger question is once you have made this determination, what are you
going to do with this info? as soon as you check, the file can be deleted
(if you just found it) or created (if you didn't find it) by another thread
or process. using the presence of a file to make a decision (esp a security
related decision) is usually a very bad idea in the long run

d
--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by unknown
Normally I use CreateFile to detect whether a file exits via checking
INVALID_HANDLE_VALUE state.
Is this the quickest way to confirm file existence ?
Any sugestion ?
Thanks,
Mike
Loading...