Page 1 of 1
FileExists
Posted: Sat Feb 11, 2017 8:16 pm
by Josh
Maybe we can have a nativ command FileExists(). Look at the following example, GetFileAttributes() is about 3 times faster than FileSize(). I don't know if there is also a similar possibility for Mac/Linux.
Code: Select all
Procedure.i FileExists (FileName$)
Define FileAttributes
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
If GetFileAttributes (FileName$) & #FILE_ATTRIBUTE_DIRECTORY = #False
ProcedureReturn #True
EndIf
CompilerCase #PB_OS_Linux
If FileSize (FileName$) > -1
ProcedureReturn #True
EndIf
CompilerCase #PB_OS_MacOS
If FileSize (FileName$) > -1
ProcedureReturn #True
EndIf
CompilerEndSelect
EndProcedure
Re: FileExists
Posted: Tue Feb 14, 2017 10:13 am
by Shardik
The following cross-platform example checks if a file exists. I have tested it succesfully on these operating systems:
- Linux Mint 18 'Sarah' x86 with PB 5.44 x86 with GTK2 and GTK3 in ASCII and Unicode mode
- Lubuntu 14.04 x86 with PB 5.44 x86 with GTK2 and GTK3 in ASCII and Unicode mode
- MacOS 10.6.8 'Snow Leopard with PB 5.44 x86 in ASCII and Unicode mode
- Windows XP SP3 x86 with PB 5.44 x86 in ASCII and Unicode mode
- Windows 7 SP1 x64 with PB 5.44 x86 and x64 in ASCII and Unicode mode
- Windows 8.1 x64 with PB 5.44 x86 and x64 in ASCII and Unicode mode
Code: Select all
Procedure.I FileExists(Filename.S)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
ProcedureReturn PathFileExists_(Filename)
CompilerCase #PB_OS_Linux
Protected UTF8Filename.S = Space(StringByteLength(Filename, #PB_UTF8) + 1)
PokeS(@UTF8Filename, Filename, -1, #PB_UTF8)
ProcedureReturn g_file_test_(UTF8Filename, #G_FILE_TEST_EXISTS)
CompilerCase #PB_OS_MacOS
ProcedureReturn CocoaMessage(0, CocoaMessage(0, 0,
"NSFileManager defaultManager"),
"fileExistsAtPath:$", @Filename)
CompilerEndSelect
EndProcedure
; ----- Output on Linux and MacOS: 0, Windows: 1
Debug "FileExists: " + FileExists(#PB_Compiler_Home + "Compilers/PBCompiler.Exe")
; ----- Output on Linux and MacOS: 1, Windows: 0
Debug "FileExists: " + FileExists(#PB_Compiler_Home + "compilers/pbcompiler")
Re: FileExists
Posted: Tue Feb 14, 2017 2:50 pm
by Josh
You can not use PathFileExists_ to check whether a file exists or not. As the name implies, it checks to see if a file or path exists with this name.
Re: FileExists
Posted: Tue Feb 14, 2017 4:35 pm
by Kiffi
Josh wrote:You can not use PathFileExists_ to check whether a file exists or not. As the name implies, it checks to see if a file or path exists with this name.
MSDN wrote:
PathFileExists function
Determines whether a path to a file system object such as a file or folder is valid.
Greetings ... Peter
Re: FileExists
Posted: Tue Feb 14, 2017 4:45 pm
by skywalk
The request is FileExists.
If a folder exists with the same name as a queried file name, then PathFileExists_(Filename$) returns #True, which is not.

Re: FileExists
Posted: Tue Feb 14, 2017 7:54 pm
by Shardik
skywalk wrote:The request is FileExists.
If a folder exists with the same name as a queried file name, then PathFileExists_(Filename$) returns #True, which is not.

skywalk is correct in that the Windows part of my example from above is not fool proof. When calling with an existing folder name like
Code: Select all
Debug "FileExists: " + FileExists(#PB_Compiler_Home + "Compilers")
the procedure will return #True. On the other side: the procedure declaration contains the parameter
Filename.S, so that it should be clear that a filename is required. So if you want to prevent a #True for an existing folder name you should use Josh's alternative. Although Josh's alternative has the drawback that you would have to use a longer winded code if a device such as a multi card interface with no cards plugged in is queried (in order to suppress an error message). Such an example had already been
posted by RichardL in 2008.
For your conveniance I have changed the Windows part of my example from above with Josh's short (and potentially displaying an unwanted error message requester) code:
Code: Select all
Procedure.I FileExists(Filename.S)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
If GetFileAttributes(FileName) & #FILE_ATTRIBUTE_DIRECTORY = #False
ProcedureReturn #True
EndIf
CompilerCase #PB_OS_Linux
Protected UTF8Filename.S = Space(StringByteLength(Filename, #PB_UTF8) + 1)
PokeS(@UTF8Filename, Filename, -1, #PB_UTF8)
ProcedureReturn g_file_test_(UTF8Filename, #G_FILE_TEST_EXISTS)
CompilerCase #PB_OS_MacOS
ProcedureReturn CocoaMessage(0, CocoaMessage(0, 0,
"NSFileManager defaultManager"),
"fileExistsAtPath:$", @Filename)
CompilerEndSelect
EndProcedure
; ----- Output on Linux and MacOS: 0, Windows: 1
Debug "FileExists: " + FileExists(#PB_Compiler_Home + "Compilers/PBCompiler.Exe")
; ----- Output on Linux and MacOS: 1, Windows: 0
Debug "FileExists: " + FileExists(#PB_Compiler_Home + "compilers/pbcompiler")
Re: FileExists
Posted: Tue Feb 14, 2017 7:56 pm
by Kiffi
skywalk wrote:If a folder exists with the same name as a queried file name, then PathFileExists_(Filename$) returns #True, which is not.

ah, ok, I have not considered that.
Thanks for clarification & Greetings ... Peter
Re: FileExists
Posted: Wed Feb 15, 2017 1:26 am
by Dude
Josh wrote:GetFileAttributes() is about 3 times faster than FileSize().
But... checking for a file's existence isn't something that's done over and over repeatedly, right? What benefit is there for having it check a little faster?
Re: FileExists
Posted: Wed Feb 15, 2017 1:45 am
by Thunder93
File synchronization software would benefit from it.

Re: FileExists
Posted: Wed Feb 15, 2017 4:02 am
by skywalk
Didn't know it was 3x faster, but I agree with the diminishing returns in comparison with more often used checksums and date modified attributes.