0

I need to read all content of a file but keep only some of the content and append new content. So I tried to use READLINES filter the lines I need to keep then rewrite the file with the kept lines and new ones:

Dim paramLines As IEnumerable
paramLines = File.ReadLines(Path & "X.ini")
Dim paramFile As StreamWriter = New StreamWriter(Path & "X.ini",append:=False)  
For Each paramline In paramLines
    if condition_iskeepIt then paramFile.WriteLine(paramline)
Next  ' paramLine

    ...write revised lines

However, this gives an error on the third line: System.IO.IOException: 'The process cannot access the file '...\X.ini' because it is being used by another process.'

What is holding the "process"? How do we get it to release?

1
  • 1
    ReadLines is not equal to ReadAllLines
    – Steve
    Commented May 19 at 20:52

2 Answers 2

1

The point of ReadLines is to read the lines one by one, so that you can process them one by one and reduce the amount of memory used, rather than loading the entire file first and then processing the lines. You haven't shown us all the relevant code so it's hard to know which is more appropriate. If you want to read and filter the existing data, then write that filtered data and some new data back to the file then you can do that with ReadLines, but you have to do it properly, e.g.

'Read the file and keep only lines that start with the specified prefix.
Dim lines = File.ReadLines(filePath).
                 Where(Function(line) line.StartsWith(prefix)).
                 ToList()

'Add a new line to be written.
lines.Add(newLine)

'Overwrite the current file contents with the combined filtered and new data.
File.WriteAllLines(filePath, lines)

However you do it, you need to enumerate the result of ReadLines first and then the file will be closed, so you can open it again to write to it. As I said, this may or may not be preferable to using ReadAllLines, depending on information that you have not provided.

0

File.ReadLines loads the file lazily. To load the lines of the file fully into memory, you can use File.ReadAllLines:

Dim paramLines As String() = File.ReadAllLines(Path & "X.ini")
Using paramFile As New StreamWriter(Path & "X.ini", append:=False)
    ' …
End Using

It is important to note that ReadAllLines loads all the file data in memory and thus (if the file is big) you will see a surge in the memory used by your application and a noticeable delay while the file is loaded.

5
  • Thanks. You are quite correct and RealAllLines (despite the typo) works. This means the doc as I quoted is wrong. I had considered adding a 500ms sleep time but it's so crude, so I owe you a few x 500ms of saved time so I can worry about other stupid problems in the world other than the error in the doc's.
    – Ernesto
    Commented May 19 at 21:05
  • @Ernesto: Note that the doc you quoted is for ReadAllLines, so it isn’t wrong. For ReadLines, no amount of sleeping would help – it keeps the file open until you’ve consumed the lines.
    – Ry-
    Commented May 19 at 21:42
  • Quite correct Ry, my error in quoting the doc link. which I edited out to reduce confusion for future readers. However, looking at the correct READLINES page it does not mention it ever letting go of the file. Although I've used it and didn't know it has that "feature" until I tried to rewrite the file immediately. If the idea is to process the lines one by one being more efficient for large files, then why not just use READLINE? I'm at a loss why READLINES is ever useful if it holds on to the file until the end of the procedure or its scope. whereas you know where you stand with READALLLINES.
    – Ernesto
    Commented May 21 at 1:21
  • @Ernesto: Memory efficiency – it’s like repeatedly using StreamReader.ReadLine in this respect, correct. The reason ReadLines exists is just to expose the convenient and composable IEnumerable API while maintaining this memory efficiency.
    – Ry-
    Commented May 21 at 2:09
  • Thanks. READLINE is nice because its streamreader has a method to close, so again you know where you stand. From what I gather READLINES does not.
    – Ernesto
    Commented May 21 at 2:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.