问题
I'm trying to encrypt a .txt
file which is created in my application.
To create this file, I'm using the following code:
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
Then, to write and encrypt the file, I'm using the following code, calling subroutines that I tweaked from examples on the internet.
bytKey = CreateKey(txtCode.Text)
bytIV = CreateIV(txtCode.Text)
EncryptOrDecryptFile(directorypath & "dbpw.txt", directorypath & "dbpw.txt", bytKey, bytIV, CryptoAction.ActionEncrypt)
When the code gets to the final line, calling the EncryptOrDecrypt
subroutine, an error is thrown saying
The process cannot access the file 'myDirectoryPath\dbpw.txt' because it is being used by another process
What do I need to do to release the file?
I also tried just using File.Create
along with File.Encrypt
but the same error was thrown either way.
Code for EncryptOrDecryptFile()
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
回答1:
Together with the parameters you pass it, in your EncryptOrDecryptFile()
method you are trying to open two streams (fsInput
and fsOutput
) to the same file. Once you've opened fsInput
it has exclusive access to the file, making fsOutput
unable to open it for writing.
Your only options are:
Rename either the input file or the output file so that the two streams open two different files, or:
Keep a "global" encryption stream open to the file, which you use every time you want to write data to it.
NOTE: Someone in the future might suggest that you open fsInput
with FileShare.Write
in order to allow other processes to open the file for writing, thus also allowing the fsOutput
stream to write to it as well. - DON'T DO THAT!
Allowing other processes to write to the file while you're reading from it can cause problems, even if it's your fsOutput
stream. This is because you'll never be able to know how much data fsOutput
is going to write. What if the encrypted data is longer than the original? That would result in it overwriting what fsInput
is going to read next, thus corrupting the file.
来源:https://stackoverflow.com/questions/45997750/encrypting-txt-file-erroring-process-cannot-access-file