【问题标题】:File still used by a processus after closing a streamwriter关闭流写入器后进程仍使用文件
【发布时间】:2016-11-04 13:50:29
【问题描述】:

最近我在处理文件。 所以我创建了一个“子”,他打开一个文件读取它并直接关闭它。在第二只手上,我重新打开它并重写它。但是有我的问题,当我这样做时,Visual Studio 告诉我该文件已被进程使用。

有我的代码,如果你发现了什么,请告诉我:

Function OpenTxt(ByVal Path As String) As String()

    'Variables
    Dim mStreamReader As StreamReader

    Dim Line As String
    Dim J As Integer
    Dim K As Integer
    Dim mStock() As String
    Dim TempTbl() As String
    Dim mSplit() As String


    'Ini
    If Not File.Exists(Path) Then

    End If
    mStreamReader = New StreamReader(Path, True)
    J = -1
    K = -1

    'Début
    Do
        Line = mStreamReader.ReadLine
        If Line <> "" Then
            mSplit = Split(Line, "||",, vbTextCompare)
            K = K + 1
            ReDim Preserve TempTbl(K)
            TempTbl(K) = Line

            Select Case mSplit(0)
                Case "IsOpen"
                    If mSplit(1) <> mEApp.LicenseKey Then

                    ElseIf mSplit(1) = 0 Then
                        TempTbl(K) = mSplit(0) & "||" & mEApp.LicenseKey
                    End If
                Case "STOCK"
                    J = J + 1
                    ReDim Preserve mStock(J)
                    mStock(J) = mSplit(1)
            End Select

        End If
    Loop Until Line Is Nothing

    mStreamReader.Close()
    mStreamReader = Nothing

    Dim mStreamWriter As StreamWriter
    mStreamWriter = New StreamWriter(Path, True)

    For K = 0 To UBound(TempTbl)
        mStreamWriter.WriteLine(TempTbl(K))
    Next

    mStreamWriter.Close()
    mStreamWriter = Nothing

    OpenTxt = mStock

    Return OpenTxt

End Function

【问题讨论】:

    标签: .net vb.net visual-studio


    【解决方案1】:

    您必须使用Using 子句

    Using mStreamReader As New StreamReader(Path, True)
    
        ' write your code here
    
    End Using
    

    在此Article 中了解有关Using 的更多信息

    你的代码会是这样的:

    Function OpenTxt(ByVal Path As String) As String()
    
    
    
        Dim Line As String
        Dim J As Integer
        Dim K As Integer
        Dim mStock() As String
        Dim TempTbl() As String
        Dim mSplit() As String
    
        'Ini
        If Not File.Exists(Path) Then
    
        End If
        Using mStreamReader As New StreamReader(Path, True)
            J = -1
            K = -1
    
            'Début
            Do
                Line = mStreamReader.ReadLine
                If Line <> "" Then
                    mSplit = Split(Line, "||", , vbTextCompare)
                    K = K + 1
                    ReDim Preserve TempTbl(K)
                    TempTbl(K) = Line
    
                    Select Case mSplit(0)
                        Case "IsOpen"
                            If mSplit(1) <> mEApp.LicenseKey Then
    
                            ElseIf mSplit(1) = 0 Then
                                TempTbl(K) = mSplit(0) & "||" & mEApp.LicenseKey
                            End If
                        Case "STOCK"
                            J = J + 1
                            ReDim Preserve mStock(J)
                            mStock(J) = mSplit(1)
                    End Select
    
                End If
            Loop Until Line Is Nothing
    
            mStreamReader.Close()
    
        End Using
    
        Using mStreamWriter As New StreamWriter(Path, True)
    
            For K = 0 To UBound(TempTbl)
                mStreamWriter.WriteLine(TempTbl(K))
            Next
    
            mStreamWriter.Close()
    
        End Using
    
        OpenTxt = mStock
    
        Return OpenTxt
    
    End Function
    

    【讨论】:

    • 您没有必须使用using,尽管通常没有充分的理由不这样做。 OP 是 Closeing 读者,应该会达到相同的结果。
    • 当使用继承 IDisposable 的对象时,建议使用Using statments。在此示例中,OP 多次使用相同的 StreamWriter 和不同的文件。所以最好使用USING statment。
    • 我不同意使用它通常是一个好主意,在这里可能是一个好主意。我不同意的是您回答中的第二个词。您没有必须使用它,在这种情况下(OP 调用 Close,它执行与 StreamReader 上的 Dispose 完全相同的清理),它应该有没有实质性影响。
    • @Damien_The_Unbeliever 在发生异常时它不会做同样的事情。我同意您不必使用using,但您可能应该使用。
    • 我按照你的建议做了,但它保持不变。有关更多信息,我在 streamreader 和 streamwriter 中使用相同的文件。事实是我不知道为什么在关闭文件后我不能用另一次流功能重新打开它。很像打开阅读的过程,在关闭指令后仍然没有关闭。
    【解决方案2】:

    您也可以使用

    读取所有行

    System.IO.File.ReadAllLines

    System.IO.File.WriteAllLines

    那么你可以这样做:

    Function OpenTxt(ByVal Path As String) As String()
    
        'Variables
        Dim Line As String
        Dim J As Integer
        Dim K As Integer
        Dim mStock() As String
        Dim TempTbl() As String
        Dim mSplit() As String
    
        Dim Lines as String() = IO.File.ReadAllLines(Path)
        J = -1
        K = -1
    
        'Début
        For Each Line in Lines
            If Line <> "" Then
                mSplit = Split(Line, "||",, vbTextCompare)
                K = K + 1
                ReDim Preserve TempTbl(K)
                TempTbl(K) = Line
    
                Select Case mSplit(0)
                    Case "IsOpen"
                        If mSplit(1) <> mEApp.LicenseKey Then
    
                        ElseIf mSplit(1) = 0 Then
                            TempTbl(K) = mSplit(0) & "||" & mEApp.LicenseKey
                        End If
                    Case "STOCK"
                        J = J + 1
                        ReDim Preserve mStock(J)
                        mStock(J) = mSplit(1)
                End Select
    
            End If
        Next
    
        IO.File.WriteAllLines(Path,TempTbl)
    
        OpenTxt = mStock
    
        Return OpenTxt
    
    End Function
    

    不需要流。一切都取决于文件的范围。更大的文件 -> 需要更多的内存。

    如果问题仍然存在,则文件可能在其他地方打开。

    【讨论】:

    • 你也可以考虑 List(of String) 而不是 Array,因为你不需要它来 ReDim
    • 您好,感谢您的提示,我明天会尝试,如果问题解决了会通知您
    • 抱歉耽搁了这么久,但结果还是一样...无法重写文件。我不明白为什么它在类库中不起作用,但在 Windows 窗体应用程序中没问题...
    • 你知道哪个进程使用了​​这个文件吗?如果您不确定,可以使用 SysInternals 的 ProcessExplorer 来查找此文件句柄并跟踪此过程。
    【解决方案3】:

    抱歉,长时间没有回复。 我回到了这个项目,我找到了答案。在这个过程之前有一个流作家是开放的,没有关闭。所以目前它运作良好。

    向大家致以最诚挚的问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      • 2015-03-29
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      相关资源
      最近更新 更多