#背景
VB.Net のソースをツールで変換するのに、UTF-8 と Shift-JIS のソースコードが混在していてわけわからなくなってきたので、エンコーディングを自動認識するコード変換ツールを作ってみました。
拡張子は、.vb 用になってますが、そのあたりは適当に。
#ソース
using System.Linq;
/// <summary>
/// エンコーディングを自動判定して、Shift-JIS のファイルを UTF-8 に変換します。
/// </summary>
/// <param name="folder">フォルダ名又は、ファイル名を指定します。</param>
private void Convert( string folder )
{
foreach( var child in System.IO.Directory.GetDirectories( folder ) ) {
this.Convert( child );
}
var sjis = System.Text.Encoding.GetEncoding( 932 );
var utf8 = System.Text.Encoding.UTF8;
foreach( var filename in System.IO.Directory.GetFiles( folder, "*.vb" ) ) {
var bytes = System.IO.File.ReadAllBytes( filename );
var bytes_SJIS = sjis.GetBytes( sjis.GetString( bytes ) );
var bytes_UTF8 = utf8.GetBytes( utf8.GetString( bytes ) );
// Shift-JIS だと、正しく認識できて、UTF-8 だと正しく認識できていない場合に、UTF-8 で書き込む
if( bytes.SequenceEqual( bytes_SJIS ) && !bytes.SequenceEqual( bytes_UTF8 ) ) {
System.IO.File.WriteAllText( filename, sjis.GetString( bytes ), utf8 );
}
}
}
#動作原理
とりあえず、ファイルをバイナリで読み込んでみて、Shift-JIS と、UTF-8 の両方で文字列に変換します。
それを、再びバイト列に戻して元のバイト列に戻るかどうかで、エンコーディングを判断しています。
どちらでも正しく認識できるのは英数字のみの場合だと思われるので、Shift-JIS での正しく認識できた場合に、utf8 で保存しています。
ログとか、バックアップファイルとかは面倒なんでとりあえず省略。