2013年6月11日火曜日

javaでBufferedReaderのreadLineで改行コードも取得させる。

javaのBufferedReaderクラスのreadLineメソッドは、実行して次の改行コードまでの文字列が戻り値に返ってくるが、改行コードは含まれない。

仕事で、ちょっとしたテキストファイルのデータ置換ツールを作成していたのですが、
そのテキストファイルは、Macで編集している人がいたり、Windowsで編集している人がいたりで、改行コードがバラバラなのです。

テキストファイルのデータの読み込みは、前述のBufferedReaderクラスのreadLineメソッドで行なっていますが、改行コードが含まれず、置換後のファイルを保存する時は、改行コードはデータ置換ツールの実行する環境に依存します。
なので、データ置換ツール実行前後の差分を確認する際に、改行コードが以前の改行コードでないから、どこがデータ置換ツールの変更対象かが分かりにくい、という問題が発生しました。
(gitのコミット前に、テキストファイルの変更箇所の差分を確認してて気づいた。)

Webで色々と検索しましたが、BufferedReaderクラスのreadLineメソッドでは、改行コードを戻り値に設定できるようなことを見つけることができませんでした。

せっかくなので、自分で、BufferedReaderクラスを拡張して、readLineメソッドの戻り値に改行コードを含むプログラムを作成してみました。

処理内容はいたって簡単です。データの読み込み時に\rか、\nがあれば、それらごと文字列を戻り値に設定するようにしただけです。

コードは以下になります。
GitHubにもアップしておきます。
https://github.com/takaharu-kobayashi/ExtendBufferedReader

package extention.java.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;

public class ExtendBufferedReader extends BufferedReader {

    public ExtendBufferedReader(Reader in) {
        super(in);
    }

    public ExtendBufferedReader(Reader in, int sz) {
        super(in, sz);
    }

    @Override
    public String readLine() throws IOException {
        int num = 0;
        StringBuilder sb = new StringBuilder();
        try {
            while ((num = this.read()) >= 0) {
                sb.append((char) num);
                switch ((char) num) {
                case '\r':
                case '\n':
                    return sb.toString();
                default:
                    break;
                }
            }
        } catch (IOException e) {
            throw e;
        }
 
        if (sb.length() == 0) {
            return null;
        } else {
            return sb.toString();
        }
    }
}