CRLFはデータ、LFは改行としたCSVファイルの読み込み
CSVファイルで、データにCRLFが入っていて、レコードの区切りがLFというものを1行ずつ処理する必要に迫られたので、作りました。言語はJavaです。実際、そんなデータがあるのかって話ですが、あるから作ったのですよ。
BufferedWriterのreadLineでは、CRLFだろうが、LFだろうが、改行コードを行の区切りとして読み込みます。今回の要件は、CRLFはデータとして、LFのみはレコードの区切りとして扱わなければなりませんので、readLineでなく、readを使ってCRLFは改行として扱わないということになります。
public class ReadLineSample {
private Reader r = null;
private static final char CR = '\r'
private static final char LF = '\n'
public ReadLineSample(Reader r) {
this.r = r;
}
public String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
// 読み込みフラグ。改行コードCRを検出した場合にON。
boolean hasCR = false;
while(true) {
int i = r.read();
if(i < 0) {
// ストリームの終端
if(sb.length() == 0) {
// バッファに文字を読み込んでいない場合
return null;
}
return sb.toString();
}
char ch = (char)i;
if(ch == LF && !hasCR) {
// 改行コードLFであり、1文字前がCRでない
return sb.toString();
}
sb.append(ch);
if(ch == CR) {
// CR
hasCR = true;
continue;
}
// フラグをOFF
hasCR = false;
}
}
}
ストリームの終端でnullを返すので、呼び出し側はBufferedReaderのreadLineを使う時と同じロジックになります。このままでも使えるし、メソッドだけをコピペしても使えます。シグネチャが同じなので、BufferedReaderのサブクラスにして、readLineをオーバーライドしても使えると思います。
実際に使いどころがあるかというと、微妙なところです。調べてみても見つからないので、晒してみようっていうだけです。ないってことは、誰もこんなもの必要としてないってことなんだろうなぁ。