- - PR -
DataInputStreamでのカレント操作
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-11-18 07:32
こんにちは。
DataInputStreamを使ってカレント操作ができないものかと 悩んでいます。 テキストファイルデータ @AAAAAAAAAAAAAAAAAAAAA ABBBBBBBBBBBBBBBBBBBBB BCCCCCCCCCCCCCCCCCCCCC CDDDDDDDDDDDDDDDDDDDDD のデータで@のデータをチェック中Aのデータの内容を 見たいのですが、できなくて困っています。 と言いますのも、 FileInputStream fis = new FileInputStream(_filepath); DataInputStream dis = new DataInputStream(fis); boolean keyFlg = true; while (keyFlg) { line = dis.readLine(); if (line == null) { keyFlg = false; } else { //次行チェック if (dis.readLine()==null) { } } } この次行チェックの為、dis.readLine()してしまっているのですが、 チェックが終わったら前行にカレントを戻したいのですが、 何かいい方法はないでしょうか? APIを見る限り無さそうですが・・。 dis.readLine()は非推奨を承知の上、あえてやってます。 よろしくお願いいたします。 | ||||||||
|
投稿日時: 2006-11-20 02:33
「次のデータを見る必要がある」ような処理では、PushbackReader/PushbackInputStreamを
使うのが普通でしょう。 DataInputStream#readLine()を使っていると素直には行かないでしょうが、 似たようなpushback操作を実装すれば良いのでは? (PushbackDataInputStream を作る) | ||||||||
|
投稿日時: 2006-11-20 03:28
エンコーディングを扱えないから非推奨だと承知しているのですよね? つまり、BufferedReaderでは扱えないバイナリ操作があるのが理由だと。 DataInputStreamは自身でバッファを一切行わないので、 BufferedInputStream#mark(int)、reset()で可能だと思います。 単にテキストを扱うだけなのであれば、
こちらが正解です。 もしくは、BufferedReader#mark(int)、reset()でも可能です。 | ||||||||
|
投稿日時: 2006-11-20 10:11
ロジックを工夫して「次行チェック」を「カレント行チェック」に書き換えられませんかね ? そうすれば「巻き戻す」処理がなくても問題ないわけですし。
この例だとkeyFlgを使わないようにできると思いますが...。 | ||||||||
|
投稿日時: 2006-11-21 13:26
ご回答ありがとうございます。
あしゅさんの教えてくださった、mark(int),reset()で 以前やってみたのですが、どうもmark取得できませんでした。 (mark(int)のint部は行数でセットしていましたが、 これが間違っていたのかも・・。) その為、以下のような処理にしました。 byte[] b = new byte[1]; b[0] = dis.readByte(); dmmy = new String(b); やりたいことが一行前が最終行である確認なので、 上ロジックで例外になったら最終行判断を行う。 ただ、1文字取り出し、ループ先頭で先頭文字としてデータに セットしています(邪道ですね)。 line = dis.readLine(); if (line!=null) { line = dmmy + line;//dis.readByte()読込時破棄してしまう為 } このように再セットすると言う汚いロジックになってしまいました。 readByte()で内容を切り取ってしまうというのは、DataInputStream もあまり親切でないな〜と感じました・・(markが扱えない私が悪いのですが)。 | ||||||||
|
投稿日時: 2006-11-21 13:35
行数じゃないですよ。バイト数です。 BufferedReaderなら文字数です。 内部的な動きとしては、 バッファを少なくとも指定されたバイト数以上を蓄えられるように拡張して、 reset()するとmark()した時の読み込み位置までバッファ上で戻ります。 そのため、mark()後に指定サイズ以上読み込んだ場合はバッファから mark()した位置のデータが無くなっている可能性があるため、 reset()に失敗する可能性があります。 | ||||||||
|
投稿日時: 2006-11-21 20:20
あしゅさん、ありがとうございます。
バイト数でしたか。 全データに対するバイト数ですと、 読み込み速度にも問題が出てきそうですね(?)。 このプログラムの仕様ですが、テキストファイルデータ を最大400Mぐらいが要求されています。 単純なreadlineなら行を読むだけですので、 現行の速度で全く問題ないのですが・・。 ありがとうございます。 | ||||||||
|
投稿日時: 2006-11-21 22:15
テキストファイルならBufferedReaderだと思うのですが・・・。 ファイル全体をreset()可能な範囲に指定する必要はないですよ。 次の行を判定する直前に毎回mark()すればよいわけです。 一行の最大長は明記されていないかもしれませんが、 一般的なバッファサイズ(4K〜8K)程度で十分でしょう。 また、次の行でどんな判定をしたいのか書いていないのでわかりませんが、 単に空行であるかを判定したいのなら、改行コード(CR+LF)の2バイト分 戻れるだけで十分です。 この場合はreadLine()は使えませんが、改行の判定程度ならすぐ作れます。 |