Reputation: 43
I've been working on a PowerShell script using Streamreader (and StreamWriter) to parse a large file into smaller reports. While doing some searching around on the best way to put this thing together, I've found there are two methods largely used to read content to the end of the file.
1 - while ($reader.Peek() -ge 0) { $line = $reader.Readline() ... }
2 - while (($line = $read.ReadLine()) -ne $null) { do stuff ... }
From the documentation, it looks like Peek will read the next value, but not change the position of the reader. It looks like ReadLine will essentially do the same, but read a whole string/line. I feel like this is a "no-duh" question - is it really more efficient to actually peek at a value before reading the line, or is it just an extra step before assigning the reader to a variable?
Thank you in advance!
Upvotes: 4
Views: 1162
Reputation: 47812
Since you need lines anyway, I see no reason to Peek()
. If you really want to check whether you're at the end, then the .EndOfStream
property is likely to be more accurate anyway.
As discussed here, .Peek()
can return -1
when errors occur as well, not just when the end of stream is reached. Most answers there also recommend avoiding it and just using .ReadLine()
.
mklement0 also mentioned using System.IO.File.ReadLines
. This returns an enumerable so you can just call it with a path and use it like other enumerables, without loading all the lines at once (so it still works with large files).
You could use it with foreach
or with ForEach-Object
, for example:
foreach ($line in ([System.IO.File]::ReadLines('path\to\file'))) {
$line
}
[System.IO.File]::ReadLines('path\to\file') | ForEach-Object -Process {
$_
}
$reader = [System.IO.File]::ReadLines('path\to\file')
foreach ($line in $reader) { $line }
$reader | ForEach-Object -Process { $_ }
Upvotes: 3