How about this (reads the last 8 bytes for a demonstration):
$fpath = "C:\10GBfile.dat" $fs = [IO.File]::OpenRead($fpath) $fs.Seek(-8, 'End') | Out-Null for ($i = 0; $i -lt 8; $i++) { $fs.ReadByte() }
UPDATE To interpret bytes as a string (but be sure to select the correct encoding - UTF8 is used here):
$N = 8 $fpath = "C:\10GBfile.dat" $fs = [IO.File]::OpenRead($fpath) $fs.Seek(-$N, [System.IO.SeekOrigin]::End) | Out-Null $buffer = new-object Byte[] $N $fs.Read($buffer, 0, $N) | Out-Null $fs.Close() [System.Text.Encoding]::UTF8.GetString($buffer)
UPDATE 2 . To read the last M lines, we will read the file in parts until the result is no longer char sequences:
$M = 3 $fpath = "C:\10GBfile.dat" $result = "" $seq = "`r`n" $buffer_size = 10 $buffer = new-object Byte[] $buffer_size $fs = [IO.File]::OpenRead($fpath) while (([regex]::Matches($result, $seq)).Count -lt $M) { $fs.Seek(-($result.Length + $buffer_size), [System.IO.SeekOrigin]::End) | Out-Null $fs.Read($buffer, 0, $buffer_size) | Out-Null $result = [System.Text.Encoding]::UTF8.GetString($buffer) + $result } $fs.Close() ($result -split $seq) | Select -Last $M
Try playing with large $buffer_size - this is ideally equal to the expected average line length to make fewer disk operations. Also pay attention to $ seq - it could be \r\n or just \n . This is very dirty code without error handling and optimization.
Aziz kabyshev
source share