你调用的对象是空的。无法读取文件并对其进行加密

时间:2015-03-30 14:42:45

标签: vb.net encryption nullreferenceexception filestream

我是VB.Net的新手。 我正在尝试读取文本文件,加密它并保存加密的文本文件。但是,当我启动加密过程时,我收到System.NullReferenceException错误。

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

调试器在行fileStreamOutput.Close()

处显示错误

请帮忙。

1 个答案:

答案 0 :(得分:0)

问题可能是第一行失败,因此在Catch变量设置之前执行会跳转到fileStreamOutput块:

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

最简单的解决方案是在Catch块中使用变量之前简单检查变量是否为空:

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

然而,正如Plutonix指出的那样,Using块会更简单。还值得一提的是,你在这个代码中做了一些其他的VB6事情,其中​​VB.NET中存在更好的替代方案。例如,您正在调用MsgBox而不是使用功能更强大的MessageBox.Show。但是,这非常小。最令人遗憾的是你使用Err对象。我必须说,超越了一个简单的分歧。 越过界限,冒犯了我的感情。在VB.NET中捕获异常的正确方法是在Catch语句中指定异常的类型。永远不要使用Err对象。

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

但是,如果您选择不使用Using块,则至少应将最后Catch更改为Finally。目前,它捕获并吃掉所有其他异常,所以如果出现其他任何问题,任何事情都不会知道。