If you already know that the very last thing of the file is a CRLF you want to get rid of (and you know the encoding too) you can go the quick route:
$stream = [IO.File]::OpenWrite('foo.txt')
$stream.SetLength($stream.Length - 2)
$stream.Close()
$stream.Dispose()
This is an in-place truncation of the file. It works without reading all the file into memory (very nice if you have a very large file). It works for ASCII, Latin-* and UTF-8. It won't work that way for UTF-16 (you'd have to remove four bytes from the end, in that case).
You can include an additional check that the last two bytes are really what you want to remove:
$stream = [IO.File]::Open('foo.txt', [IO.FileMode]::Open)
$stream.Position = $stream.Length - 2
$bytes = 0..1 | %{ $stream.ReadByte() }
$compareBytes = 13,10 # CR,LF
if ("$bytes" -eq "$compareBytes") {
$stream.SetLength($stream.Length - 2)
}
$stream.Close()
$stream.Dispose()
Again, adapt if you use another encoding, e.g. for UTF-16 you need to compare to either 0,10,0,13
or 10,0,13,0
.
Agreed, this is not very PowerShell-ey, but ever since I had to process a 700-MiB database dump I am wary of reading potentially large files into memory completely ;)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…