Bits of Java (トップ)

VM   JDK と JRE
Language   オブジェクトとインスタンス   this と super   static   フィールドアクセス
IO   Serializable の実装
Swing   MetalLookAndFeel   イメージパネル
JavaBeans   プロパティ名について   XMLEncoder で保存
その他   正規表現テストアプリ   秀丸の強調表示   Ant のインストール   文字セット変換 Ant タスク   XAMPP + Tomcat

文字エンコーディングと改行文字を変更しながらディレクトリをコピーする Ant タスク

文字エンコーディングと改行文字を変更する Ant タスクの紹介です。 BSDライセンスで公開しています。 このタスクはディレクトリのコピーを行いますが、その際にビルドファイルに設定されている内容に沿って拡張子ごとに文字エンコーディングと改行文字を変換します。 Ant を使ってプログラムのソースや設定ファイルなどの文字エンコーディングや改行文字をまとめて変更する場合を想定しています。 機能は限られていますが、ほとんどの場合で Ant(1.6 以上) の Copy タスクで同じ事を行うよりもビルドファイルの設定は簡単になります。

下はビルドファイルの設定例です。 Ant で changecharset を実行すると src ディレクトリを dest ディレクトリ直下にコピーします。 コピーの際に拡張子 java と txt の付いたファイルは windows-31j を使ってファイルを読み込み、コピー先では文字エンコーディングに EUC-JP を、改行文字には LF を使って書き出します。 同様に拡張子 xml や xsd の付いたファイルはコピー先の改行文字は LF になります。 src ディレクトリに含まれているファイルで java txt xml xsd 以外の拡張子の付いたファイルや拡張子の無いファイルは内容の変更は行われずにバイナリコピーされます(バイトを読み込みそのまま書き出します)。 また charsetinfo 要素で設定している拡張子の付いたファイルでも文字エンコーディングや改行文字の変更の必要が無い場合にはバイナリコピーします。

  <target name="changecharset">
    <taskdef name="cschange"
             classname="jp.gr.java_conf.boj.anttask.cschanger.CharsetChanger"/>
    <cschange srcdir="src" destdir="dest" deep="true">
      <charsetinfo extensions="java txt" in="windows-31j" out="EUC-JP" outls="LF"/>
      <charsetinfo extensions="xml xsd" in="UTF-8" out="UTF-8" outls="LF"/>
    </cschange>
  </target>

コピーもとから設定されている文字エンコーディングを使ってテキストファイルを読み込む際にバイトを文字列(ユニコード)に変換できない場合にはユニコードの置換文字(REPLACEMENT CHARACTER → U+FFFD) に変換されます。 置換文字(U+FFFD) はユニコードで表現できない文字がそこにある事を意味しており、表示に関してはそれを扱っているプログラムに依存し、通常は特定の記号や図形などに置き換えられます。 これは Java でテキストを読み込む際のデフォルトの動作です。 設定されている文字エンコーディングを使ってコピー先にテキストを書き出す場合にバイト列に変換できない文字がある場合には文字 ? となるバイト (byte)0x3f に置き換えられます。 これも Java でテキストを書き出す際のデフォルトの動作で、ユニコードでは表現できる文字が使用する文字セットには含まれていないというケースが多いようです。 CharsetChanger タスクは文字エンコーディングや改行文字を変更したファイルをコピー先に書き出す際に ? に置き換えられた部分があるとログで知らせます。 これらのファイルの ? の部分は元のファイルの文字には戻せないので注意が必要です。

インストールはこちらから cschanger.zip をダウンロードしてお使いの解凍ツールか jar コマンドで任意のディレクトリに解凍してください。 JDK (1.4以降) と Ant はインストール済みとします。(Ant のインストール方法
jar で解凍する場合のコマンドは
jar xf cschanger.zip
です。 cschanger.zip を解凍すると cschanger ディレクトリが作成されその中には build.xml と license.txt そしてソースファイルを格納した src ディレクトリが含まれています。 build.xml は UTF-8 で記述されています。 インストールはコマンドプロンプトやターミナルなどで cschanger ディレクトリに移動して以下のコマンドを実行するだけです。
ant
BUILD SUCCESSFUL と表示されれば問題なくインストールは終了です。 build.xml にデフォルトのターゲットとして記述されている createjar が実行され、 src にあるソースファイルをコンパイルして build/classes ディレクトリにクラスファイルを出力し、それを cschanger.jar にパックして ANT_HOME/lib ディレクトリに配置します。 もしもうまくいかない場合には JDK や Ant がインストール済みで環境変数 JAVA_HOME や ANT_HOME が正しく設定されているかどうかを確認してください。

続いてにタスクが正しく実行されるかテストします。
ant changecharset
を実行すると src_eucjp ディレクトリが作成されそこに src ディレクトリがコピーされます。 src_eucjp ディレクトリの Java ソースは文字エンコーディングが EUC-JP に改行文字が LF に変更されています。 以上でインストールとテストは終了です。 タスクの実行に必要なのは ANT_HOME/lib/cschanger.jar だけなので cschanger.zip や cschanger ディレクトリ以下はすべて破棄してくださって結構です。

CharsetChanger タスクを実行するビルドファイルの例を以下に示します。 処理の内容は前出の通りです。 ビルドファイルのファイル名は通常 build.xml にします。 ビルドファイル名が build.xml の場合にはコマンドラインで -buildfile オプションなどによりビルドファイルを指定する必要がなくなります。
<?xml version="1.0" encoding="UTF-8"?>
<project name="ChangeCharset" default="changecharset">
  <target name="changecharset">
    <taskdef name="cschange"
             classname="jp.gr.java_conf.boj.anttask.cschanger.CharsetChanger"/>
    <record name="cschange_log.txt" action="start"/>
    <cschange srcdir="src" destdir="dest" deep="true">
      <charsetinfo extensions="java txt" in="windows-31j" out="EUC-JP" outls="LF"/>
      <charsetinfo extensions="xml xsd" in="UTF-8" out="UTF-8" outls="LF"/>
    </cschange>
    <record name="cschange_log.txt" action="stop"/>
  </target>
</project>

タスクの実行はコマンドプロンプトやターミナルでこの build.xml のあるディレクトリに移動して 以下のコマンドを実行するだけです。
ant
実行時に cschange_log.txt ファイルがカレントディレクトリにログとして出力されます。 このファイルの内容は標準出力に表示されるものと同じなので、コピー先へファイルを書き出す際に ? への置き換えが発生した場合などにメッセージが読みづらくなる可能性があるので、そのような場合に使用してください。

ビルドファイルの最初のプロセッシングインストラクション(XML宣言)の encoding にはファイルを記述した文字エンコーディングを指定します。 省略した場合には UTF-8 と見なされます。 日本語を使用している場合には正しい文字エンコーディングを指定する必要があります。

taskdef 要素でタスク名を定義し、タスククラスとそのクラスパスを指定します。 上の設定の場合は CharsetChanger タスクを cschange という名前のタスクで実行できるようになります。

赤い部分がコピーに関する設定と文字エンコーディングや改行文字に関する設定部分です。 cschange という要素名は taskdef 要素の name 属性で設定した名前(任意)と同じでなければなりません。 cschange の属性にはコピーに関する設定を行います。 cschange の属性の設定内容は以下です。

srcdir コピー対象のディレクトリの絶対パスまたは Ant を実行するディレクトリからの相対パス。
指定したディレクトリも含めてコピーされる。
存在しない場合やディレクトリではない場合にはエラーとなる。
省略不可。
destdir コピー先のディレクトリの絶対パスまたは Ant を実行するディレクトリからの相対パス。
指定したディレクトリ内に srcdir で指定したディレクトリがコピーされる。
コピー先に srcdir で指定したディレクトリやそのサブディレクトリを指定した場合でも、一度コピー対象のディレクトリやファイルのリストを作成してからコピーを始めるので問題ない。
指定したディレクトリが存在しない場合には作成を試み、成功したら srcdir で指定したディレクトリをコピーする。
指定したディレクトリが存在する場合に、その中に srcdir で指定したディレクトリと同じ名前のディレクトリやファイルが存在する場合にはエラーとなる。
省略不可。
deep true か false を指定する。
(実際には true yes on のどれかが true を表し、それ以外は false となる) srcdir 以下のディレクトリツリーすべてをコピーする場合は true を指定し、 srcdir 直下にあるファイルやディレクトリのみをコピーし、srcdir 直下のディレクトリの内部以下はコピーしない場合 は false を指定する。
省略可能で、デフォルトは true となりサブディレクトリ以下すべてをコピーする。

cschange 要素にネストされている charsetinfo 要素は拡張子ごとの文字エンコーディングや改行文字の設定を行います。 いくつでも設定可能で、1つも設定しない場合にはただのディレクトリのコピーになります(OS のコピー機能とは異なり更新日時などのファイル情報は失われます)。 日本語を使用する際によく使われる文字エンコーディングには次のようなものがあります。
windows-31j Shift_JIS EUC-JP ISO-2022-JP UTF-8 UTF-16
charsetinfo 要素の属性の設定は以下です。

extensions in out outls で指定する文字エンコーディングや改行文字を適用するファイルの拡張子を指定する。
設定が同じとなる拡張子が複数ある場合は、半角スペースで区切って記述する。
タスク内で1つの拡張子を2回以上定義しようとするとエラーになる。
省略不可。
in コピーもとから extensions で指定した拡張子の付いたテキストファイルを読み込む際に使用する文字エンコーディング。
サポートされていない文字エンコーディングを指定した場合にはエラーとなる。
省略不可。
out コピー先に extensions で指定した拡張子の付いたテキストファイルを書き込む際に使用する文字エンコーディング。
文字エンコーディングを変更しない場合には in と同じ文字エンコーディングを指定する。
サポートされていない文字エンコーディングを指定した場合にはエラーとなる。
省略不可。
outls コピー先に extensions で指定した拡張子の付いたテキストファイルを書き込む際に使用する改行文字。
LF もしくは CRLF を指定する(実際には CRLF 以外は LF と解釈する)。
省略不可。