ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Java質問&情報提供サイトコミュのEOFについて(readLine使用)

  • mixiチェック
  • このエントリーをはてなブックマークに追加
readLine()で読み込んだ1行を処理するプログラムを作っています。

readLine()で改行すると空行(長さ0のString)になってEOFがあるとnullが返ってきます。
ここまではわかるのですが、1枚目の画像のように文字の隣にEOFがある場合はその1行が読み取られません。
2枚目の画像のように空行を入れれば読み取れるのですが・・・

その行にEOFがあっても読み取れる方法は何かありませんか?
1行単位で後の処理をしたいのでなるべく行単位で読み込みたいです。
空行を入れろというのは無しでお願いします。

下記は現在のソースです。
/**
* 対象のブロックを摘出した後,変換して出力させる.
* @param read 読み込み
*/
public static void convateReadLine(BufferedReader read) {

List<String> list = null; //ブロックのリスト
String word = null; //ブロックの内容

while (true) {

try {

word = read.readLine(); //1行分を読み込む

} catch (IOException e) {

e.printStackTrace();

}

/* EOFを検出した場合,処理を終了する.
* そうでなければブロックの変換を続ける.*/
if (word == null) {

break;

}

/*空行が入力された場合はブロックの変換を行う.
*リストが空の場合はブロックの読み込みに戻る.*/
if (word.length() <= 0) {

/*リストにブロックが格納されているとき*/
if (list != null) {

/*ブロックごとに変換し,出力する.*/
createBlock(list).print(System.out);
System.out.println();

/*次のブロック格納のためnullに初期化*/
list = null;

}

continue;

}

/*先頭が#(コメント指定)ではない場合*/
if (! word.startsWith("#")) {

/*リストがnullのとき,新しくリストを生成する.*/
if (list == null) {

list = new ArrayList<String>();

}

/*生成したリストに読み込んだブロックを格納する.*/
list.add(word);

}

}

}

コメント(6)

勘違いしていませんか?
EOFはテキストファイルのコード上、基本的には存在しませんよ。
改行は1又は2バイトあるので、readLineで読めます。

TeraPadなどは最後にEOFを「表示」してくれているだけです。

詳しく知りたいなら、バイナリエディターでそれぞれのテキストファイルを開いてみてください。
「ファイルの中にEOFがある(EOFは実態がある何か)」と考えずに、「ファイルから最後の一個を読み込んだ時からそのファイルの状態がEOFになる(EOFは状態)」(EOFを読み込むと・・・ではことにも注意)と考えてください。
# EOFの状態のファイルからさらに読み込もうとすると、EOFというイベント(例外)が発生するとか、擬似的にEOFを返す・・・という言語も多い。とりあえず読み込みに失敗した返しておいて、原因は他の関数で調べてね という言語もある・・・

# EOFが文字コードて存在して、かつ、それが意味を持っていたのは、CP/Mのころ?

あとは、readLineが定義している「1行」も調べてみてください。普段使用している概念(というか、勝手に期待している動作)が、言語が定義しているものと必ずしも一致するとは限らないので、名称などから判断すると、思わぬ落とし穴にはまることがあります(調べたら解決する・・という意味での指摘ではなく、そーゆーことがある というレベルの話です)
次のように書けば、すべての行がlinesに入ります(改行コードは含まれない)。
最後に[EOF]で終わっている行も読み込めます。

String charset = "UTF-8";
BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset));
List<String> lines = new ArrayList<String>();
String line = null;
while((line=r.readLine()) != null){
  lines.add(line);
}
r.close();
たくさんのコメントありがとうございます。

檸檬さん>
>EOFはテキストファイルのコード上、基本的には存在しませんよ。
>改行は1又は2バイトあるので、readLineで読めます。
>TeraPadなどは最後にEOFを「表示」してくれているだけです。
はい、存在しないのはわかっています。
改行にバイトがあるのは知りませんでした。なので空行として処理されるのですね。
Terapadで書いたのはEOFや改行の位置を見やすくするためでした。

うぇいくさん>
>「ファイルから最後の一個を読み込んだ時からそのファイルの状態がEOFになる(EOFは状態)」
つまりファイルの内容を1行ずつ読み込んでいくとすると、
最後の行を読み込んだ=ファイルの状態がEOFに、という解釈してよかったんですね。
>普段使用している概念(というか、勝手に期待している動作)が、言語が定義しているものと必ずしも一致するとは限らない
はい。間違った解釈をしているかもしれませんし、もう一度調べてみます。

kouさん>
>***[EOF]の行もlist.add(word);で追加されていて、次の1行読込みでnullが返り、word==nullが真となり、
ブロックごとに変換し出力する処理とやらをする前に永久ループを抜けていることが原因かと思います。
なるほど。ちゃんと読み込んでいるのに処理する前に破棄しているということですね。
もう一度その部分を見直してみます。

たぁぼさん>
ソースコードありがとうございます。
みなさんのコメントと合わせて参考にさせていただきます。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Java質問&情報提供サイト 更新情報

Java質問&情報提供サイトのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング