FileExists

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

FileExists

Post 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
sorry for my bad english
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: FileExists

Post 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")
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: FileExists

Post 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.
sorry for my bad english
User avatar
Kiffi
Addict
Addict
Posts: 1486
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: FileExists

Post 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
Hygge
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: FileExists

Post 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. :wink:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: FileExists

Post 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. :wink:
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")
Last edited by Shardik on Tue Feb 14, 2017 7:57 pm, edited 1 time in total.
User avatar
Kiffi
Addict
Addict
Posts: 1486
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: FileExists

Post 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. :wink:
ah, ok, I have not considered that.

Thanks for clarification & Greetings ... Peter
Hygge
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: FileExists

Post 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?
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: FileExists

Post by Thunder93 »

File synchronization software would benefit from it. :wink:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: FileExists

Post 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.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply