よくあるテキストファイルの文字コード変換ですが、サイズが大きくなるとエディターで開いて、文字コードを指定して保存して・・・というのが辛くなりますよね。 そこで、Windows標準機能のPowershellで、文字コードを変換してみます。
前提
以下の例では、Windows上でUnicode(UTF-16リトルエイディアン)で保存されているファイルを、シフトJISに変換するサンプルになっています。要件に合わせて、適宜指定する文字コードを変えてください 変数[$From]に変換前の、変数[$To]に変換後の、ファイルフルパスを予め入れているものとします
例)
$FromFilePath = "C:\Temp\unicode.txt" $ToFilePath = `C:\Temp\sjis.txt`
ワンライナー版
数十MB程度までのファイルを文字コード変換するなら、標準のコマンドレットで簡単にできます。 (ただし、powershellプロセスが、ファイルサイズ+αのメモリーを消費します)
Get-Content -Encoding Unicode $FromFilePath | Set-Content $ToFilePath
dotNet Framework 版(StreamReader、StreamWriter)
数百MBあるような大き目のファイルを文字コード変換するときは、標準のコマンドレット(get-content、set-content)でやると、システムリソースを消費しすぎるため、StreamReader、StreamWriterクラスを使って、ファイルI/Oをバッファリングしてあげます。速度もそこそこで、メモリー使用量も抑えられのがありがたい。
Function Convert-Charset
{
param
(
[String] $From,
[String] $To
)
# set buffer size to 4MB
$StreamReaderBufferSize = 4 * 1024 * 1024
$StreamWriterBufferSize = 4 * 1024 * 1024
Try
{
# charset name: utf-8 Shift_Jis Unicode
# reference http://www.atmarkit.co.jp/ait/articles/0304/11/news004.html
$Reader = New-Object System.IO.StreamReader( $From, `
[Text.Encoding]::GetEncoding(`Unicode`), $false, `
$StreamReaderBufferSize)
$Writer = New-Object System.IO.StreamWriter( $To, `
$false, [Text.Encoding]::GetEncoding(`Shift_Jis`), `
$StreamWriterBufferSize)
# read all line, and write all line
While( -not ($Reader.EndOfStream) )
{
$Writer.WriteLine( $Reader.ReadLine() )
}
} Catch {
Write-Error $Error[0].Exception.ErrorRecord
throw $_.Exception
} Finally {
$Writer.Close()
$Reader.Close()
}
}
convert-charset -From $FromFilePath -To $ToFilePath
バッファーサイズは、実行環境のメモリーに余裕があれば、例では4MBですが、32MB程度に増やした方がスループットが出る場合もあるので、試しながら調整してください。 文字コード指定のキーワードは、@ITさんの記事が分かりやすいので、参考にされてください