PowerShell 讀取檔案各種寫法利弊
讀檔的方式其實蠻多的這邊大致介紹一下區別與效能影響
Get-Content
這是最常見的最快速的方法讀取出來是一個陣列物件,依照每行分配。
在絕大多數情況下是最方便快速的。
使用範例
Get-Content $Path
唯一的問題大概就是 Encoding 有限,只能用萬國碼或當前電腦編碼。還有性能沒有使用C#函式來得好。
[System.IO.File]::ReadAllLines()
遇到Encoding問題的時候首選的方案是這個,可以自由的設定編碼,而且有著較好的效能。
編碼問題大概比較容易遇到的狀況是
- 在舊版的 5.1 需要輸出不帶BOM的UTF8
- 非電腦編碼的其他語言
這兩種狀況都不是 Get-Content 能解決得,只能使用C#的函式
使用範例
$Enc = [Text.Encoding]::GetEncoding('UTF-8')
[System.IO.File]::ReadAllLines($Path, $Enc)
如果希望讀進來的不是陣列,使用 ReadAllText() 讀進來會是有換行的字串
要說缺點大概就是這東西不支持流,不支持流有個大問題是對於記憶體消耗比較重,假設今天要搬一個100G大小的文件,記憶體就得有100G才行,如果支持流可以讀一行寫一行自然對記憶體的負擔比較小了。
System.IO.StreamReader
這個大概是最好使的利器了,性能跟 ReadAllLines 一樣,而且支持流讀取與自訂 Encoding。檔案的指標移動也有支持,跟其他語言的讀取檔案差不多意思。
相比於前面這個函式是唯一可以解決缺少結尾空行的辦法了,前兩個其實都有個問題是會吃到一行結尾空行,因為for迴圈是在內部運行的,無權干預,這個可以自己寫能有效避開缺行的問題。
使用範例
$StreamReader = New-Object System.IO.StreamReader($Path, $Enc)
while ($null -ne ($line = $StreamReader.ReadLine())) {
$line
}
if ($null -ne $StreamReader) { $StreamReader.Dispose() }
缺點也是一目了然,前後要開檔關檔還要寫 While 迴圈,對於快速測試來說這東西絕對不是首選。
Encoding編碼表查詢
最後附上各種常見編碼的查詢方法
# 日文::Shift-JIS (932)
[Text.Encoding]::GetEncoding('Shift-JIS')
# 簡體中文::GB2312 (936)
[Text.Encoding]::GetEncoding('GB2312')
# 繁體中文::BIG5 (950)
[Text.Encoding]::GetEncoding('BIG5')
# 萬國碼::UTF8 (65001)
[Text.Encoding]::GetEncoding('UTF-8')
# 萬國碼::UTF8-BOM (65001)
(New-Object System.Text.UTF8Encoding $True)
# 萬國碼::UTF8-NonBOM (65001)
(New-Object System.Text.UTF8Encoding $False)
# 當前系統編碼
PowerShell -Nop "& {return [Text.Encoding]::Default}"
# 當前 PowerShell 編碼
[Text.Encoding]::Default
沒有留言:
張貼留言