我使用的是vb.NET和windows窗体。 我有一个带有列表框和两个按钮的简单表单。 btnLoadData打开一个OpenFileDialog并允许我选择要打开的文本文件,然后将其读入列表框。
然后我可以从列表框中删除项目。
btnSaveList打开一个SaveFileDialog,允许我选择要保存的文件。
当我尝试保存到我读入的同一文件时,会出现问题。 它告诉我该文件在使用时无法访问。如果我选择一个新的文件名,它会起作用。
我搜索并尝试了许多不同的建议。我已多次修改代码,最后我决定要求帮助!
两个按钮的代码如下。
Private Sub btnLoadData_Click(sender As Object, e As EventArgs) Handles btnLoadData.Click
Dim openFD As New OpenFileDialog()
openFD.Filter = "Text [*.txt*]|*.txt|CSV [*.csv]|*.csv|All Files [*.*]|*.*"
openFD.ShowDialog()
openFD.OpenFile()
Dim objReader As New StreamReader(openFD.SafeFileName)
While objReader.Peek <> -1
lstList.Items.Add(objReader.ReadLine)
End While
objReader.Close()
End Sub
Private Sub btnSaveList_Click(sender As Object, e As EventArgs) Handles btnSaveList.Click
Dim saveFD As New SaveFileDialog()
If saveFD.ShowDialog = Windows.Forms.DialogResult.OK Then
Using objWriter As New StreamWriter(saveFD.FileName) 'Throws the exception here
For Each line In lstList.Items
objWriter.WriteLine(line)
Next
End Using
End If
End Sub
Private Sub lstList_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstList.SelectedIndexChanged
lstList.Items.Remove(lstList.SelectedItem)
End Sub
谢谢。
答案 0 :(得分:3)
您创建了两个流,但只在读取文件结束时关闭了一个流。 OpenFileDialog
的{{3}}方法正在创建一个您最后没有关闭的流,因此它保持打开并锁定文件。在您的情况下,您使用自己的流,因此您不需要方法OpenFile()
。
按钮#1的代码(读取文件):
openFD.Filter = "Text [*.txt*]|*.txt|CSV [*.csv]|*.csv|All Files [*.*]|*.*"
openFD.ShowDialog()
'openFD.OpenFile()
Using objReader As New StreamReader(openFD.FileName)
While objReader.Peek <> -1
lstList.Items.Add(objReader.ReadLine)
End While
End Using
按钮#2的代码(写入文件):
Dim saveFD As New SaveFileDialog()
If saveFD.ShowDialog = Windows.Forms.DialogResult.OK Then
Using objWriter As New StreamWriter(saveFD.FileName)
For Each line In lstList.Items
objWriter.WriteLine(line)
Next
End Using
End If
答案 1 :(得分:2)
打开要读取的文件将锁定文件以防止写入和删除;打开要写入的文件将锁定读取,写入和删除。
您可以覆盖这些锁,但同时尝试读取和写入文件会产生一系列问题。
有两种方法可以避免这种情况:
在处理和写入之前读取整个文件并关闭。当然,整个内容必须在记忆中。
写入临时文件,关闭输入并完成写入后删除原始文件并重命名临时文件。如果没有额外的步骤,这将不会保留属性(例如所有权,ACL)。
但是在您的情况下,我怀疑您需要使用using
block来确保文件在读取后关闭,而不是依赖于GC在将来的某个时刻关闭它。