可以打开并从文件中读取但不能重新保存到同一个文件

时间:2017-11-28 08:18:47

标签: vb.net

我使用的是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

谢谢。

2 个答案:

答案 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)

打开要读取的文件将锁定文件以防止写入和删除;打开要写入的文件将锁定读取,写入和删除。

您可以覆盖这些锁,但同时尝试读取和写入文件会产生一系列问题。

有两种方法可以避免这种情况:

  1. 在处理和写入之前读取整个文件并关闭。当然,整个内容必须在记忆中。

  2. 写入临时文件,关闭输入并完成写入后删除原始文件并重命名临时文件。如果没有额外的步骤,这将不会保留属性(例如所有权,ACL)。

  3. 但是在您的情况下,我怀疑您需要使用using block来确保文件在读取后关闭,而不是依赖于GC在将来的某个时刻关闭它。