よくあるテキストファイルの文字コード変換ですが、サイズが大きくなるとエディターで開いて、文字コードを指定して保存して・・・というのが辛くなりますよね。 そこで、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さんの記事が分かりやすいので、参考にされてください