Androidのアプリ開発関連のブログ

末尾改行問題に対応した

BufferedReader.readline()だと末尾が改行か違うかがわからない件で対応コード書いた。

読み込み部分
String lf="\n";
BufferedReader buf=new BufferedReader(new InputStreamReader(in,charset));
StringBuffer sb=new StringBuffer();
int c;
while((c=buf.read())!=-1){
   if(c==10){
     sb.append("\n");
     while((c=buf.read())!=-1){
       sb.append((char)c);
     }
   break;
   }else if(c==13){
    sb.append("\n");
    if((c=buf.read())==10){
       lf="\r\n";
    }else{
      lf="\r";
      if(c!=-1) sb.append((char)c);
    }
    while((c=buf.read())!=-1){
      if(c==10) continue;
      if(c==13){
        sb.append("\n");
      }else{
        sb.append((char)c);
      }
    }
    break;
  }
  sb.append((char)c);
}
buf.close();
結局readline()せずに1文字ずつ読むことにした。
改行コードの取得が必要なしょりなんだが、最初の改行で判別する。
元々LFかCRLFの2種類にだけ対応させてたが、ついでなんでCRのみにも対応させた。
CRLFとCRのループ処理は分けたほうがループ内処理が1行減らせるが、基本はLFでCRLFとCR滅多に無いと思うんで共通処理にした。
最初にLFが出現したら基本的にコード内にCRは無いはずなので、全部StringBufferにそのまま格納。
最初にCRが出現したら取得文字列にはLFを格納して、つづく文字でCRかCRLFかを判別。
以降はLFは無視してCR→LF変換。

書き込み部分
OutputStreamWriter writer=new OutputStreamWriter(out,charset);
BufferedReader buf=new BufferedReader(new StringReader(str));
String line;
if(str.endsWith("\n")){
  while((line=buf.readLine())!=null){
    line+=lf;
    writer.write(line,0,line.length());
  }
}else{
  if((line=buf.readLine())!=null){
    writer.write(line,0,line.length());
    while((line=buf.readLine())!=null){
      line=lf+line;
      writer.write(line,0,line.length());
    }
  }
}
buf.close();
writer.close();
読み込み時に変換しているので元文字列にはCRは無い。
元文字列の末尾文字を判別して、末尾が改行かそうでないかで処理を分けてreadline()使う。
末尾が改行なら普通に1行読んで改行コードを追加。
末尾が改行でない場合は、1行目を書き込んで、2行目以降は行末ではなく先頭に改行を追加する感じ。

条件によって処理が2通りになるからコード量増えちゃうが、正確に処理できたほうが良いよね。