41

指定された InputStream がバッファリングされていないものであるかどうかがわかっている場合、InputStream を常に BufferedInputStream としてラップすることは理にかなっていますか? 例:

InputStream is = API.getFromSomewhere()
if(!(is instanceof BufferedInputStream))
  return new BufferedInputStream(is);
return is;
4

4 に答える 4

35

指定されたInputStreamがバッファリングされていないものであるかどうかがわかっている場合、常にInputStreamをBufferedInputStreamとしてラップすることは意味がありますか?

いいえ。

大量の小さな読み取り(一度に1バイトまたは数バイト)を実行する可能性がある場合、またはバッファリングされたAPIによって提供される高レベルの機能の一部を使用する場合は理にかなっています。たとえば、BufferedReader.readLine()メソッド。

read(byte[])ただし、および/またはメソッドを使用して大きなブロック読み取りのみを実行する場合はread(byte[], int, int)、をラップするInputStreamことBufferedInputStreamは役に立ちません。

(@Peter Tillmanの自身の回答に対するコメントに応えて、ブロック読み取りのユースケースは間違いなくクラスの使用の0.1%以上を表しています!!ただし、バッファリングされたAPIを使用することは通常無害InputStreamであるという意味で彼は正しいですする必要はありません。)

于 2010-06-03T10:16:51.923 に答える
6

私はそれをしません。可能な限り最高の抽象化レベルのままにしておきます。BufferedStream のマークおよびリセット機能を使用しないのであれば、わざわざそれをラップする必要はありません。

消費者がそれを必要とする場合は、そこにラップすることをお勧めします。

于 2010-06-03T07:44:53.710 に答える
3

常にバッファリングが必要なわけではないため、答えは No です。場合によっては、単なるオーバーヘッドです。

それが「いいえ」である別の理由があり、それはより深刻な場合があります。BufferedInputStream(またはBufferedReader) ソケットでタイムアウトも有効にしている場合、ネットワーク ソケットで使用すると、予期しないエラーが発生する可能性があります。タイムアウトは、パケットの読み取り中に発生する可能性があります。そのポイントに転送されたデータにアクセスできなくなります-ゼロ以外のバイト数があることを知っていたとしても(変数が利用可能なjava.net.SocketTimeoutExceptionサブクラスであるjava.io.InterruptedIOExceptionことを参照してください)。bytesTransferred

読み取り中にソケット タイムアウトがどのように発生するのか疑問に思っている場合は、read(bytes[])メソッドを呼び出すと、メッセージを含む元のパケットが分割されてしまい、部分的なパケットの 1 つがタイムアウト (またはタイムアウトの残りの部分) を超えて遅延することを考えてみてください。 )。これは、実装する何か(またはまたはメソッドjava.io.DataInputなどの複数バイト値の読み取りのいずれか) に再度ラップされた場合に、より頻繁に発生する可能性があります。readLong()readFully()BufferedReader.readLine()

java.io.DataInputStreamタイムアウト例外でもうまく動作しないため、タイムアウトのあるソケット ストリームの候補としても不適切であることに注意してください。

于 2010-06-03T11:20:19.137 に答える
0

また、InputStream から読み取る方法にも依存します。一度に文字/バイトを読み取る場合 (つまり、read())、BufferedInputStream は、ユーザーに代わって大量の読み取りを静かに実行することにより、オーバーヘッドを削減します。一度に 4k または 8k バイト/文字配列にブロックを読み込む場合、BuffredInputStream はおそらく役に立ちません。

于 2010-06-03T07:56:40.877 に答える