0

I have a Sub that reads a file that was created in another Sub. I'm getting an error

Can't access file in use in other process

From what I've read on the net I need to close the StreamReader. I've tried to use .close() on different variables, but nothing seems to work.

Below is the code that writes the file the other Sub then accesses.

Private Sub CreateGraphicsFunction(sender As Object, e As EventArgs)

    Dim Regex = New Regex("infoEntityIdent=""(ICN.+?)[""].*?[>]")
    strGraphicFile = MoveLocation & "\ICN-LIST.txt"

    Dim ICNFiles = Directory.EnumerateFiles(MovePath, "*.*", SearchOption.AllDirectories)

    For Each tFile In ICNFiles
        Dim input = File.ReadAllText(tFile)

        Dim match = Regex.Match(input)
        If match.Success Then
            output.Add(match.Groups(1).Value)
        End If
    Next
    File.WriteAllLines(strGraphicFile, output)
    locationGraphicsLog = strGraphicFile

End Sub

The other Sub that reads the file created

 Private Sub btnFindICN_Click(sender As Object, e As EventArgs) Handles btnFindICN.Click


    Application.UseWaitCursor = True
    Application.DoEvents()
    Me.Refresh()

    Dim sGraphicFilesToFind As String
    Dim graphicLocation As String
    'MoveWithPath As String
    Dim graphicFile As String

    graphicLocation = txtSearchICN.Text
    MoveLocation = MovePath

    graphicLogFile = MoveLocation & "\Reports\1-OrphanedFilesItems.txt"
    Dim FILE_NAME As String
    FILE_NAME = MoveLocation & "\ICN-LIST.txt"


    Dim objReader As New System.IO.StreamReader(FILE_NAME)
    Dim sGraphicFile As String

    Do While objReader.Peek() <> -1
        graphicFile = objReader.ReadLine()
        sGraphicFilesToFind = graphicLocation & "\" & graphicFile & "*.*"
        sGraphicFile = graphicFile
        Dim createGraphicReportFldr As String

        Dim paths() As String = IO.Directory.GetFiles(graphicLocation, sGraphicFile, IO.SearchOption.AllDirectories)
        If paths.Count = 0 Then
            'Debug.Print(graphicFile)
            If System.IO.File.Exists(graphicLogFile) = True Then
                Dim objWriter As New System.IO.StreamWriter(graphicLogFile, IO.FileMode.Append)
                objWriter.WriteLine(graphicFile)
                objWriter.Close()
            Else
                'MsgBox("Creating Orphaned graphicFile Now. ")

                createGraphicReportFldr = MoveLocation & "\Reports"
                If Not IO.Directory.Exists(createGraphicReportFldr) Then
                    IO.Directory.CreateDirectory(createGraphicReportFldr)
                    'MsgBox("folder created" & createGraphicReportFldr)

                    Dim writeFile As IO.StreamWriter
                    writeFile = IO.File.CreateText(graphicLogFile)
                    writeFile.Write(graphicFile & vbCrLf)
                    writeFile.Close()
                Else
                    'MsgBox("Folder already exist")
                End If
            End If
        Else
            For Each pathAndFileName As String In paths
                Dim createGraphicsFolder As String
                'Dim moveFileToNewFolder As String

                If System.IO.File.Exists(pathAndFileName) = True Then
                    Dim sRegLast As String = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
                    Dim toGraphiicFileLocation As String

                    'MsgBox("sRegLast " & sRegLast)
                    fileGraphicLoc = MoveLocation & sRegLast
                    createGraphicsFolder = MoveLocation & "\Figures"
                    moveGraphicFileToNewFolder = MoveLocation & "\Figures\" & sRegLast
                    toGraphiicFileLocation = createGraphicsFolder & "\" & sRegLast
                    'MsgBox("FileLoc " & fileLoc)

                    If Not IO.Directory.Exists(createGraphicsFolder) Then
                        IO.Directory.CreateDirectory(createGraphicsFolder)
                        ' MsgBox("folder created" & createGraphicsFolder)
                    End If

                    If System.IO.File.Exists(fileGraphicLoc) = False Then
                        System.IO.File.Copy(pathAndFileName, moveGraphicFileToNewFolder)
                        Debug.Write("Graphics moved to : " & moveGraphicFileToNewFolder & vbCrLf)
                    End If
                End If

            Next
        End If
    Loop
    'MsgBox("graphicFiles have been moved")

    Call CreateGraphicsFunction(Nothing, System.EventArgs.Empty)
    Application.UseWaitCursor = False
    Application.DoEvents()
    ' Me.Close()
End Sub
Watercayman
  • 7,970
  • 10
  • 31
  • 49
mightymax
  • 431
  • 1
  • 5
  • 16
  • On which line do you get the error message? – Steve Jul 18 '19 at 20:53
  • Possible duplicate of [IOException: The process cannot access the file 'file path' because it is being used by another process](https://stackoverflow.com/questions/26741191/ioexception-the-process-cannot-access-the-file-file-path-because-it-is-being) – Ken White Jul 18 '19 at 20:53
  • File.WriteAllLines(strGraphicFile, output) is where i get the error – mightymax Jul 18 '19 at 20:56
  • The only other place I have output is File.WriteAllLines(strGraphicFile, output) and declaring the variable – mightymax Jul 18 '19 at 20:58
  • *"a Sub that reads a file"* - You should show that one, too. You've only shown where you write the file. – madreflection Jul 18 '19 at 21:05
  • How about the "other Sub" you reference? How is the file opened and closed? – djv Jul 18 '19 at 21:05
  • I've added the code that reads the ICN-LIST.txt file – mightymax Jul 18 '19 at 21:07
  • You never closed/disposed of `objReader`. Note that you can open a `FileStream` with `FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite` and read/write from/to it from somewhere else, if you need to. With caution. Always dispose of the Stream when you're done with it. – Jimi Jul 18 '19 at 21:12
  • OMG I feel so stupid I'm calling the write function after the read function. Call CreateGraphicsFunction(Nothing, System.EventArgs.Empty) – mightymax Jul 18 '19 at 21:12
  • `Application.DoEvents()` is code smell. You should run the processing code on a non-UI thread. – djv Jul 18 '19 at 21:15
  • You may also want to read the entire file at once then dispose of the stream. There is no reason to leave it open while you are doing the processing on the strings therein. – djv Jul 18 '19 at 21:17
  • Wait now the code won't run at all. – mightymax Jul 18 '19 at 21:18
  • The second Sub isn't doing anything now. I press the button and nothing happens. I know that's not specific. I'm trying to get a exact location – mightymax Jul 18 '19 at 21:25
  • The code runs until If paths.Count = 0 Then. It never moves to the Else part of the code. – mightymax Jul 18 '19 at 21:34
  • OK it looks like path.count is always 0 now – mightymax Jul 18 '19 at 21:43

1 Answers1

1

In the "other Sub", change

Dim objReader As New System.IO.StreamReader(FILE_NAME)

to

Using objReader = New System.IO.StreamReader(FILE_NAME)

and add End Using where you are done with it. Probably right after Loop. This will ensure that the disposable stream is always disposed.

See Using Statement (Visual Basic). You almost always want to wrap an IDisposable object in a Using block if you are able to restrict its scope to a single method.

djv
  • 15,168
  • 7
  • 48
  • 72