0

I am new to VB.Net. I am trying to read a text file, encrypt it and save the encrypted text file. However when I start the encrypt process, I get a System.NullReferenceException error.

Private Sub encryptOrDecrypt(ByVal strInputFile As String, ByVal strOutputFile As String, _
                           ByVal byteKey() As Byte, ByVal byteInitializationVector() As Byte, _
                           ByVal Process As CryptoProcess)

    Try

        'File stream for handling file IO
        fileStreamInput = New System.IO.FileStream(strInputFile, FileMode.Open, FileAccess.Read)
        fileStreamOutput = New System.IO.FileStream(strOutputFile, FileMode.OpenOrCreate, FileAccess.Write)
        'Ensure that output file is empty
        fileStreamOutput.SetLength(0)

        'Declaring variables for encryption and decryption process
        Dim byteBuffer(4096) As Byte
        Dim bytesProcessed As Long = 0
        Dim fileLength As Long = fileStreamInput.Length
        Dim intBytesInCurrentBlock As Integer
        Dim csCryptoStream As CryptoStream

        Dim cryptoRijnadel As New System.Security.Cryptography.RijndaelManaged

        Select Case Process
            Case CryptoProcess.EncryptFile
                csCryptoStream = New CryptoStream(fileStreamOutput, _
                                                  cryptoRijnadel.CreateEncryptor(byteKey, byteInitializationVector), _
                                                  CryptoStreamMode.Write)
            Case CryptoProcess.DecryptFile
                csCryptoStream = New CryptoStream(fileStreamOutput, _
                                                  cryptoRijnadel.CreateDecryptor(byteKey, byteInitializationVector), _
                                                  CryptoStreamMode.Write)
        End Select

        While bytesProcessed < fileLength
            intBytesInCurrentBlock = fileStreamInput.Read(byteBuffer, 0, 4096)
            csCryptoStream.Write(byteBuffer, 0, intBytesInCurrentBlock)
            bytesProcessed = bytesProcessed + CLng(intBytesInCurrentBlock)
        End While
        csCryptoStream.Close()
        fileStreamInput.Close()
        fileStreamOutput.Close()

        If Process = CryptoProcess.EncryptFile Then
            Dim fileOriginal As New FileInfo(strFileToEncrypt)
            fileOriginal.Delete()
        End If

        Dim Wrap As String = Chr(13) + Chr(10)
        If Process = CryptoProcess.EncryptFile Then
            MsgBox("Done", MsgBoxStyle.Information, "Done")
        End If

    Catch When Err.Number = 53
        MsgBox("File not found", MsgBoxStyle.Exclamation, "Invalid File")
    Catch
        fileStreamInput.Close()
        fileStreamOutput.Close()

    End Try
End Sub

The debugger shows the error at the line fileStreamOutput.Close()

Please help.

seankoh
  • 35
  • 1
  • 10

1 Answers1

0

The problem is likely the fact that the first line fails, so execution jumps to the Catch block before the fileStreamOutput variable gets set:

fileStreamInput = New System.IO.FileStream(strInputFile, FileMode.Open, FileAccess.Read)
fileStreamOutput = New System.IO.FileStream(strOutputFile, FileMode.OpenOrCreate, FileAccess.Write)

The simplest solution would be to simply check if the variable is null before using it in the Catch block:

Catch
    If fileStreamInput IsNot Nothing Then
        fileStreamInput.Close()
    End If
    If fileStreamOutput IsNot Nothing Then
        fileStreamOutput.Close()
    End If
End Try

However, as Plutonix pointed out, a Using block would be simpler. It's also worth mentioning that you are doing some other VB6-ish things in this code where better alternatives exist in VB.NET. For instance, you are calling MsgBox rather than using the more functional MessageBox.Show. However, that's very minor. The most regrettable thing is your use of the Err object. That, I must say, goes beyond a simple disagreement in preference. That crosses the line into offending my sensibilities. The proper way to catch exceptions in VB.NET is to specify the type of the exception in the Catch statement. You should never use the Err object, ever.

Try
    Using fileStreamInput As New System.IO.FileStream(strInputFile, FileMode.Open, FileAccess.Read)
        Using fileStreamOutput As New System.IO.FileStream(strOutputFile, FileMode.OpenOrCreate, FileAccess.Write)
            ' ...
        End Using
    End Using
Catch ex As FileNotFoundException
    MessageBox.Show("File not found", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try

If, however, you choose to not use the Using blocks, you should, at the very least, change the last Catch to Finally. Currently, it catches and eats all other exceptions, so if anything else goes wrong, nothing will know about it.

Steven Doggart
  • 43,358
  • 8
  • 68
  • 105
  • Now I am getting a System.UnathorizedAccessException. I am not able to save the output file to the location I have selected. – seankoh Mar 31 '15 at 01:08
  • Yes, that's the exception I was most expecting that you would be getting. It just means that the current user (the one under which your process is being run) doesn't have sufficient OS privileges of open that particular file. – Steven Doggart Mar 31 '15 at 11:43