ほんじゃーねっと

おっさんがやせたがったり食べたがったりする日常エッセイ

指定したフォルダ内のファイルの文字コードをUTF-8に変換するタスク

指定フォルダ内の全ファイルについて、文字コードを自動判定して読み込み、
UTF-8に変換して保存するカスタムタスクを作成する。


文字コード自動判定については、下記のページでJcode.pmを参考にした関数が
紹介されているので、そちらを使わせていただく。
http://dobon.net/vb/dotnet/string/detectcode.html


紹介されているGetCode関数を、UtilsフォルダにJcode.csとして保存したとする。


作ったタスクはこんな感じ。
文字コードShift_JISEUC-JPの場合のみUTF-8に変換するようにしてる。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using MyTasks.Utils;
namespace MyTasks.Tasks
{
[TaskName("encode2utf8")]
class Encode2UTF8Task : Task
{
private string _dirPath;
[TaskAttribute("dir", Required = true)]
[StringValidator(AllowEmpty = false)]
public string DirPath
{
get { return this._dirPath; }
set { this._dirPath = value; }
}
protected override void ExecuteTask()
{
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(this._dirPath);
IEnumerable<System.IO.FileInfo> fileList = dirInfo.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
var queryMatchingFiles = from file in fileList
select file.FullName;
System.Text.Encoding enc_utf8 = System.Text.Encoding.GetEncoding("utf-8");
System.Text.Encoding enc = null;
System.IO.FileStream fs = null;
byte[] bs = null;
foreach (string fileName in queryMatchingFiles)
{
fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
bs = new byte[fs.Length];
fs.Read(bs, 0, bs.Length);
fs.Close();
enc = Jcode.GetCode(bs);
if (enc != null)
{
if (enc.CodePage == 932 || enc.CodePage == 51932)
{
System.IO.File.WriteAllText(fileName, enc.GetString(bs), enc_utf8);
Log(Level.Info, string.Format("{0}から{1}に変換しました: {2}", enc.EncodingName, enc_utf8.EncodingName, fileName));
}
}
}
}
}
}


buildファイルにはこんな感じでタスクを定義する

  <target name="load">
<loadtasks assembly="C:\ht\data\workspace\MyTasks\MyTasks\bin\Debug\MyTasks.dll" />
</target>
<target name="encode2utf8" depends="load">
<if test="${not property::exists('dirPath')}">
<property name="dirPath" value="${basic::getInput()}" />
</if>
<encode2utf8 dir="${dirPath}" />
</target>


使う時は、コマンドプロンプトで下記のようなコマンドを実行する

nant encode2utf8 -D:dirPath=C:\sjis_folder


既存ファイルを上書きしちゃうので、使う時はご注意ください。