← Back to context

Comment by coliveira

2 years ago

I believe some people used that monster version because VB had simple libraries that didn't allow many options. Anything more complex required you to go down the Win32 rabbit hole. And that was the main weakness of VB, it was such a simple language that you didn't have many options to do something more complex than going straight to Win32.

It is a very different thing to claim "the language doesn't allow simple things such as checking for a file's existence" (which is false, the language allows many ways to do so) than to claim "the language doesn't have many options, but allows you to interop with the entire win32 API if you need to". The first is a valid if only false complain; the second reads to me not as a complain, but as a feature.

  • >to claim "the language doesn't allow simple things such as checking for a file's existence" (which is false,

    That's not what I wrote. I said there's no _built-in_ way to check existence of the file. A reasonable interpretation of "built-in" is for an obvious named function such as "File.exists()" _without_ cobbling together extra workarounds and hacks -- whether those workarounds include re-purposing other VB built-in functions with On Error ... or using Win32 interop.

    > in VB, [...] would at worse be comprised of a exception handler (on error ...)

    That's an example of what I meant of not being built-in to VB. I should have been more clear. We were using different meanings of "builtin".

    In any case, the following "pure" VB code to check for file existence is not found on Google or Bing search but I still have it from my 1995 archives and copied it here. It has many lines of code (instead of a simple "one-liner") because it tries to cover all the edge cases. And yet with all that defensive code, there's still a hidden timebomb of a bug in it. Can anyone spot it? The code is unmodified from Visual Basic Programmer's Journal. In contrast, the alternative using Win32 interop with OF_EXISTS doesn't have the bug.

      Dim strTestFilename As String
      strFilename = Trim(strFilename)
    
      ' To avoid problem with known bug, don't pass root directory to
      ' the Name function
        Select Case Right$(strFilename, 1)
            Case "\": strExistsFilename = "Root": Exit Function
            Case "\.": strExistsFilename = "Root": Exit Function
            Case "\..": strExistsFilename = "Root": Exit Function
        End Select
    
        On Local Error Resume Next      ' Enable error trapping for Name function
        Name strFilename As strFilename ' A trick to see if filename/path is good
    
      ' Now check the resulting err code of the Name function
        Select Case Err
            Case 5  ' Illegal function call
            Case 53 ' File not found
            Case 58         ' File exists (maybe)
                strTestFilename = Dir$(strFilename)
                If Len(strTestFilename) Then
                    strExistsFilename = ""      ' It's a file
                Exit Function
                Else
                    strExistsFilename = "Dir"   ' It's a directory
                    Exit Function
                End If
            Case 64 ' Bad filename
            Case 68 ' Device unavailable
            Case 71 ' Disk not ready
            Case 75 ' Access denied
            Case 76 ' Path not found
        End Select
    

    My point was that C# builtin File.Exists() is a lot simpler than that.

    • So, what is so wrong about simply calling FileLen() to check if the file exists, or if you also want to distinguish between Files/Directories using GetAttr to check the directory bit ? Why do you have to go all the way to this monster of code which even hardcodes lists of errors (why do you care which error it is?) ?

      Your code sample renames the file, then globs anyway (when dir$ by itself can also be used to check existence). It looks too convoluted, and I cannot imagine why it needs to be so.

      What is exactly the corner case that you want to avoid -- and if such case really exists, why are you so sure the File.Exists() implementation would not fall into the same pit trap, considering it also simply uses the metadata?

      Disclaimer: I'm only familiar with VBA, not VB itself. But these file metadata functions definitely already exist in 95's VB5. (EDIT: Actually 97's. Maybe the problem is these functions did not exist in earlier VBs? But I would find it hard to imagine you could not check a file's size).

      The sample code smells even in the trivial-case checks. E.g. Right$(_, 1) will only return a 1-char string at most, yet it tries to compare it with 2, 3 len strings. I didn't check any further than that.

      5 replies →