- - PR -
BufferedInputStream#available()が0をかえす
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-03-24 22:56
お世話になります。
掲題の件ですが、BufferedInputStream#available()が0をかえす ことがあるということを見かけたのですが、 これは一体どういうケースの時になるのでしょうか? もし、わかる方がいらっしゃいましたら教えて下さい。 http://java-house.jp/ml/archive/j-h-b/008795.html [ メッセージ編集済み 編集者: JBOY 編集日時 2004-03-24 22:58 ] | ||||||||||||
|
投稿日時: 2004-03-24 23:57
BufferedInputStreamがラップしているInputStreamがソケットやパイプ、標準入力などの場合、バッファリングされているデータの量が0なら、available()は0を返すようです。
例えば下記のコードを実行した場合、コンソールに何か文字列を入力してEnterキーを押す(標準入力にバッファリングされているデータ量が0以上になる)まで、System.out.println("available="+bin.available())の行には到達しません。
| ||||||||||||
|
投稿日時: 2004-03-25 13:11
InputStreamがファイルならは起こらないということでしょうか?
buf.lengthが0になることがあるのかと思っていました。 上記の参照記事はソケットやパイプの時の話なのでしょうか? http://www.atmarkit.co.jp/fjava/rensai2/webopt07/webopt07.html の記事にあるようにこのような事がavailable()でも起こるのかなと考えていました。 | ||||||||||||
|
投稿日時: 2004-03-25 14:17
java.io.InputStream#available()のAPIドキュメントを読んでみると良いと思います。
ちなみに、FileInputStream#available()はnativeメソッドですので、実際に返す値はJVM側の実装によります。BufferedInputStream#available()が返す値は、「自分自身がバッファリングしているデータ量+ラップしているInputStreamのavailabe()が返す値」ですね。 | ||||||||||||
|
投稿日時: 2004-03-25 17:16
勘違いにより恥ずかしいことを書いていたので削除![ メッセージ編集済み 編集者: 佐々木 編集日時 2004-03-25 18:21 ] | ||||||||||||
|
投稿日時: 2004-03-26 09:37
unibon です。こんにちわ。
http://www.atmarkit.co.jp/fjava/rensai2/webopt07/webopt07.html から引用しますと、
と書かれている中の、BufferedInputStream でラップする必要はないと思います。これだとバッファを二重に使っていることになります。ただ、別にロジック的に悪くはないし、一般に、この程度の冗長さは BufferedInputStream の使用時に限らず、随所でおこなうものなのであまり気にしなくても良いと思います。 #ということを問われているのかな、と思ったのですが、消えてました。 | ||||||||||||
|
投稿日時: 2004-03-26 11:43
皆様ありがとうございます。
完璧ではないですが、段々わかってきました。 ただ、いつも思うのですが、 JVMの実装次第というところがいつも気になる今日この頃です。。 | ||||||||||||
|
投稿日時: 2004-03-26 13:14
そのとおりです。「自分でバッファリングするならBufferedInputStreamを使う意味はない」ということを言いたかったのです。 それをなぜ消したかと言えばですね。 ぼくはこういう場合、BufferedInputStreamの性能を信じ切って1バイト単位のread()をよく使うのですが、計測してみるとこれが自前バッファリングより10倍近く遅かったわけです(生の1バイトread()よりは50倍以上速いのですが)。そういうわけで、「確かめもせずに適当なことを書いてしまったなぁ」と反省して削除したわけでした。 ま、しかし、あのコードが妙であるということは確かですね。 まとめると、 * 自分でバッファリングするならBuffered*でくるむ必要はない。 * しかし、Buffered*でくるんだからといってint read()はやはりちょっと重い。(ここが僕の勘違いポイントでした。充分速いと思っていた。) ということです。 ちなみに計測条件と結果は以下のようなものです。 テスト概要: 21.2MBのファイルを読み込むのに要する時間を計測。 OS: Windows2000 JDK: IBM製の1.3 結果: (1) バッファリング無しの1バイトread(): 38578ms (2) BufferedInputStreamでの1バイトread() 578ms (3) 自前で1024バイトのバッファを使ってread(byte[]) 62ms | ||||||||||||
