Vb.net Encrypting.txt文件出错-进程无法访问文件

Vb.net Encrypting.txt文件出错-进程无法访问文件,vb.net,encryption,file-access,Vb.net,Encryption,File Access,我正在尝试加密应用程序中创建的.txt文件 要创建此文件,我将使用以下代码: Dim fileExists As Boolean = File.Exists(directorypath & "dbpw.txt") If File.Exists(directorypath & "dbpw.txt") = False Then Using sw As New StreamWriter(File.Open(directorypath & "dbpw.txt", FileM

我正在尝试加密应用程序中创建的
.txt
文件

要创建此文件,我将使用以下代码:

Dim fileExists As Boolean = File.Exists(directorypath & "dbpw.txt")
If File.Exists(directorypath & "dbpw.txt") = False Then
   Using sw As New StreamWriter(File.Open(directorypath & "dbpw.txt", FileMode.Create))
         IIf(fileExists, "", "")
         sw.Close()
   End Using
End If
然后,为了编写和加密文件,我使用下面的代码,调用我从互联网上的示例中调整的子程序

bytKey = CreateKey(txtCode.Text)
bytIV = CreateIV(txtCode.Text)

EncryptOrDecryptFile(directorypath & "dbpw.txt", directorypath & "dbpw.txt", bytKey, bytIV, CryptoAction.ActionEncrypt)
当代码到达最后一行时,调用
EncryptOrDecrypt
子例程,将抛出一个错误:

进程无法访问文件“myDirectoryPath\dbpw.txt”,因为另一个进程正在使用该文件

我需要做什么才能发布该文件

我还试着只使用
File.Create
File.Encrypt
一起使用,但无论哪种方法都会抛出相同的错误

EncryptOrDecryptFile()的代码

Public Sub-encryptorsecryptfile(ByVal strInputFile作为字符串,ByVal strOutputFile作为字符串,ByVal bytKey()作为字节,ByVal bytIV()作为字节,ByVal Direction作为加密操作)
尝试
fsInput=New System.IO.FileStream(strInputFile、FileMode.Open、FileAccess.Read)
fsOutput=New System.IO.FileStream(strOutputFile、FileMode.OpenOrCreate、FileAccess.Write)
fsOutput.SetLength(0)
'当前失败,文件创建后不会释放以进行读/写。
Dim bytBuffer(4096)作为字节
当长度=0时,处理的小字节数
Dim lngFileLength As Long=fsInput.Length
Dim INTBYTESINRENTBLOCK为整数
Dim csCryptoStream作为加密流
Dim cspRijndael作为新系统。安全性。加密。RIJNDAEL管理
选择案例方向
Case CryptoAction.ActionEncrypt
csCryptoStream=新加密流(fsOutput_
cspRijndael.CreateEncryptor(bytKey,bytIV)_
CryptoStreamMode.Write)
Case CryptoAction.ActionDecrypt
csCryptoStream=新加密流(fsOutput_
cspRijndael.CreateDecryptor(bytKey,bytIV)_
CryptoStreamMode.Write)
结束选择
而LngBytes进程小于lngFileLength
IntByteInsirrentBlock=fsInput.Read(bytBuffer,04096)
csCryptoStream.Write(bytBuffer,0,intBytesInCurrentBlock)
LNGBytes处理=LNGBytes处理+_
CLng(INTBYTESINRENTBLOCK)
结束时
csCryptoStream.Close()
fsInput.Close()
fsOutput.Close()
特例
错误日志(ex)
结束尝试
端接头

以及您传递的参数,在您的
EncryptOrDecryptFile()
方法中,您正试图将两个流(
fsInput
fsOutput
)打开到同一个文件。打开
fsInput
后,它将以独占方式访问该文件,从而使
fsOutput
无法打开该文件进行写入

您唯一的选择是:

  • 重命名输入文件或输出文件,使两个流打开两个不同的文件,或者:

  • 保持文件的“全局”加密流处于打开状态,您每次想向其写入数据时都会使用该加密流

注意:将来可能会有人建议您使用
FileShare.Write打开
fsInput
,以允许其他进程打开文件进行写入,从而也允许
fsOutput
流对其进行写入。-不要那样做


在读取文件时允许其他进程写入文件可能会导致问题,即使它是您的
fsOutput
流。这是因为您永远无法知道要写入多少数据
fsOutput
。如果加密数据比原始数据长,该怎么办?这将导致它覆盖下一步要读取的内容,从而损坏文件。

以及您传递给它的参数,在
EncryptOrDecryptFile()
方法中,您试图打开同一文件的两个流(
fsInput
fsOutput
)。打开
fsInput
后,它将以独占方式访问该文件,从而使
fsOutput
无法打开该文件进行写入

您唯一的选择是:

  • 重命名输入文件或输出文件,使两个流打开两个不同的文件,或者:

  • 保持文件的“全局”加密流处于打开状态,您每次想向其写入数据时都会使用该加密流

注意:将来可能会有人建议您使用
FileShare.Write打开
fsInput
,以允许其他进程打开文件进行写入,从而也允许
fsOutput
流对其进行写入。-不要那样做


在读取文件时允许其他进程写入文件可能会导致问题,即使它是您的
fsOutput
流。这是因为您永远无法知道要写入多少数据
fsOutput
。如果加密数据比原始数据长,该怎么办?这将导致它覆盖下一步要读取的
fsInput
,从而损坏文件。

调用
sw.Close()
是多余的,因为您将它包装在
Using/End Using
块中。至于您的问题,问题可能是底层流没有关闭。与其使用
File.Open()
直接将文件名传递给
StreamWriter
使用sw作为新的StreamWriter(directorypath&“dbpw.txt”)
@visualincent我本来没有
sw.Close()
,我只是将其添加进来看看它是否解决了问题。我按照您的建议将代码更改为
使用sw作为新的StreamWriter(directorypath&“dbpw.txt”,FileMode.Create)
,但它仍然抛出相同的错误。与问题无关,但
FileMode.Create在该条件下无效
Public Sub EncryptOrDecryptFile(ByVal strInputFile As String, ByVal strOutputFile As String, ByVal bytKey() As Byte, ByVal bytIV() As Byte, ByVal Direction As CryptoAction)

    Try
        fsInput = New System.IO.FileStream(strInputFile, FileMode.Open, FileAccess.Read)
        fsOutput = New System.IO.FileStream(strOutputFile, FileMode.OpenOrCreate, FileAccess.Write)
        fsOutput.SetLength(0)
        ' Currently fails, file not being released for read/write once it's created.

        Dim bytBuffer(4096) As Byte
        Dim lngBytesProcessed As Long = 0
        Dim lngFileLength As Long = fsInput.Length
        Dim intBytesInCurrentBlock As Integer
        Dim csCryptoStream As CryptoStream

        Dim cspRijndael As New System.Security.Cryptography.RijndaelManaged

        Select Case Direction
            Case CryptoAction.ActionEncrypt
                csCryptoStream = New CryptoStream(fsOutput, _
                cspRijndael.CreateEncryptor(bytKey, bytIV), _
                CryptoStreamMode.Write)

            Case CryptoAction.ActionDecrypt
                csCryptoStream = New CryptoStream(fsOutput, _
                cspRijndael.CreateDecryptor(bytKey, bytIV), _
                CryptoStreamMode.Write)
        End Select

        While lngBytesProcessed < lngFileLength
            intBytesInCurrentBlock = fsInput.Read(bytBuffer, 0, 4096)

            csCryptoStream.Write(bytBuffer, 0, intBytesInCurrentBlock)

            lngBytesProcessed = lngBytesProcessed + _
                                    CLng(intBytesInCurrentBlock)
        End While

        csCryptoStream.Close()
        fsInput.Close()
        fsOutput.Close()

    Catch ex As Exception
        errorLog(ex)

    End Try
End Sub