0

I've got the following function that when it opens a file to establish the file type doesn't return the correct value. What am I doing wrong?

The first 8 characters are in this format %PDF-1.4

Function GetFileType(xFile As String) As Boolean
    Dim fileBytes As Byte()

    fileBytes = System.IO.File.ReadAllBytes(xFile)

    Dim s As String
    s = System.Text.Encoding.UTF8.GetString(fileBytes)

    Select Case s
        Case s.Substring(1, 3) = "PDF"
            GetFileType = False
        Case Else
            GetFileType = True
    End Select

End Function

It doesn't match the case statement, it's always moves to the else part which has me stumped.

user2496011
  • 67
  • 3
  • 12
  • Use the debugger and look at the values. – LarsTech Sep 05 '19 at 21:54
  • I've used the debugger, the values look correct! – user2496011 Sep 05 '19 at 22:03
  • `Select Case s.Substring(1, 3)` `Case "PDF"` – LarsTech Sep 05 '19 at 22:03
  • VB.NET doesn't actually support this kind of Case statement syntax. Option Strict On allows the compiler to tell you about it. Consider a simple If-statement instead. – Hans Passant Sep 05 '19 at 22:08
  • For file signature detection, you'd be better off doing a byte-wise comparison. Besides being more reliable (converting to UTF-8 could result in invalid characters about which you don't care), you don't have to read the whole file to determine that those 8 bytes match the signature. Open a `FileStream`, read up to 8 bytes, and compare (against the characters of the signature's *ASCII* characters as byte values). – madreflection Sep 05 '19 at 22:15
  • Well, you learn something new every day. Thanks Hans! – user2496011 Sep 05 '19 at 22:20
  • madreflection, I'm open to improvements, can you point me to some code to get started? – user2496011 Sep 05 '19 at 22:25
  • @user2496011: [This answer in C#](https://stackoverflow.com/a/16014518) is pretty close to what I was suggesting. It also compares just the constant part of the header, `"%PDF-"`, so you don't get false negatives on other versions (assuming you don't want to be limited to 1.4 files). – madreflection Sep 05 '19 at 23:07

1 Answers1

2

Why are you trying to use a case statement?

In this case (see what I did there?), a simple If will work:

Function GetFileType(xFile As String) As Boolean
    Dim fileBytes As Byte()

    fileBytes = System.IO.File.ReadAllBytes(xFile)

    Dim s As String
    s = System.Text.Encoding.UTF8.GetString(fileBytes)

    if s.Substring(1, 3) = "PDF" then
            GetFileType = False
    Else
            GetFileType = True
    End If

End Function
daShier
  • 2,056
  • 2
  • 8
  • 14
  • 1
    Or just GetFileType = s.SubString(1, 3) <> "PDF". – Hans Passant Sep 05 '19 at 22:23
  • @HansPassant, excellent catch! But I still would suggest the simple `If Then Else` since it provides a more generalized method that works for more situations than this special case. – daShier Sep 05 '19 at 22:27