web-dev-qa-db-ja.com

BufferedReaderはバイトを読み取ることができますか?

この質問が重複している場合は申し訳ありませんが、探していた回答が得られませんでした。

Javaドキュメントはこれを言います

一般に、リーダーで作成された各読み取り要求により、対応する読み取り要求が基になる文字またはバイトストリームで作成されます。したがって、FileReaders>やInputStreamReadersなど、read()操作にコストがかかる可能性のあるリーダーの周りにBufferedReaderをラップすることをお勧めします。例えば、

BufferedReader in = new BufferedReader(new FileReader("foo.in"));

指定されたファイルからの入力をバッファリングします。バッファリングがないと、read()またはreadLine()を呼び出すたびに、バイトがファイルから読み取られ、文字に変換されてから返される可能性があり、これは非常に非効率的です。

  1. 私の最初の質問は bufferedReaderがバイトを読み取ることができる場合、bufferedreaderを使用してバイト単位の画像を処理できないのはなぜですか。

  2. 私の2番目の質問は Bufferedreaderは文字をBUFFERに格納しますか?この行の意味は何ですか

指定されたファイルからの入力をバッファリングします。

  1. 私の3番目の質問はこの行の意味は何ですか

一般に、リーダーで作成された各読み取り要求により、対応する読み取り要求は、基になる文字またはバイトストリームで作成されます。

13
TruePS
  1. デフォルトの動作では文字に変換されますが、画像がある場合は文字データを取得できず、代わりにバイト単位のデータが必要です。そのため、使用できません。

  2. これはバッファリングです。つまり、char配列内の特定のデータチャンクを読み取っています。この動作は次のコードで確認できます。

 public BufferedReader(Reader in) {
               this(in, defaultCharBufferSize);
            }

defaultCharBufferSizeは以下のとおりです。

private static int defaultCharBufferSize = 8192;

3 Every time you do read operation, it will be reading only one character.

つまり、簡単に言うと、文字データのいくつかのチャンクを最初に読み取り、char配列に保持して処理し、ストリームの終わりに達するまで同じデータのチャンクを再度読み取ります。

詳細については、以下を参照してください。

BufferedReader

3
UVM

ここには2つの質問があります。

1。バッファリング

あなたが最寄りの水源から1マイル離れたところに住んでいて、1時間ごとに1杯の水を飲むと想像してみてください。ええと、あなたはすべてのカップのために水までずっと歩くことはないでしょう。 1日1回行って、カップを24回満たすのに十分な水で満たされたバケツを持って帰宅します。

バケットはバッファです。

あなたの村が川から水を供給されていると想像してみてください。しかし、川が1か月間枯渇することもあります。また、川が大量の水をもたらし、村が洪水に見舞われることもあります。だからあなたはダムを建設し、ダムの後ろに貯水池があります。貯水池は雨季には満杯になり、乾季には徐々に空になります。村は一年中安定した水が流れています。

リザーバーはバッファーです。

コンピューティングのデータストリームは、これらの両方のシナリオに似ています。たとえば、1回のOSシステムコールでファイルシステムから数キロバイトのデータを取得できますが、一度に1文字を処理する場合は、リザーバーに似たものが必要です。

BufferedReaderには、川である別のReader(たとえば、FileReader)と、リザーバーであるバイトの配列が含まれています。あなたがそれから読むたびに、それは次のようなことをします:

_ if there are not enough bytes in the "reservoir" to fulfil this request
      top up the "reservoir" by reading from the underlying Reader
 endif
 return some bytes from the "reservoir".
_

ただしBufferedReaderを使用する場合、知る必要はありませんhow動作しますが、動作するだけです。

2。画像への適合性

BufferedReaderとFileReaderはReadersの例であることを理解することが重要です。プログラミング教育でポリモーフィズムをまだカバーしていない可能性があるので、カバーするときはこれを覚えておいてください。つまり、FileReaderを使用するコードがあるが、その側面のみがReaderに準拠している場合は、BufferedReaderに置き換えることができ、それは正しく機能します。同じ。

動作する最も一般的なクラスとして変数を宣言するのは良い習慣です。

_ Reader reader = new FileReader(file);
_

...バッファリングを追加するために必要な変更は、これだけになるためです。

_ Reader reader = new BufferedReader(new FileReader(file));
_

画像にあまり適していないのはすべてReadersなので、私はその回り道をしました。

Readerには2つのreadメソッドがあります。

_ int read(); // returns one character, cast to an int
 int read(char[] block); // reads into block, returns how many chars it read
_

2番目の形式は、intではなくcharを確実に読み取るため、画像には適していません。

最初の形式は問題ないように見えます-結局のところ、intを読み取ります。実際、FileReaderを使用するだけであれば、うまくいく可能性があります。

ただし、FileReaderにラップされたBufferedReaderがどのように機能するかを考えてください。 BufferedReader.read()を初めて呼び出すと、FileReader.read(buffer)が呼び出されてバッファーがいっぱいになります。次に、バッファの最初のcharをintにキャストして戻し、それを返します。

特に、マルチバイト文字セットを画像に取り込むと、問題が発生する可能性があります。

したがって、整数を読み取りたい場合は、InputStreamではなくReaderを使用してください。 InputStreamにはint read(byte[] buf, int offset, int length)があります-バイトは、charよりもintからはるかに確実に前後にキャストされます。

7
slim

Javaのリーダー(およびライター)は、テキスト(文字)ストリームを処理するための特殊なクラスです。行の概念は、他のタイプのストリームでは意味がありません。

一般的なIO同等のものについては、 BufferedInputStream をご覧ください。

だから、あなたの質問に答えるために:

  1. リーダーは最終的にバイトを読み取りますが、それらを文字に変換します。他のもの(画像など)を読み取ることは意図されていません-そのためにクラスのInputStreamファミリーを使用してください
  2. バッファリングされたリーダーは、基になるストリーム(ファイル、ソケット、またはその他のもの)からメモリ内のバッファにデータの大きなブロックを読み取り、バッファが空になるまでこのバッファからの読み取り要求を処理します。毎回小さなチャックではなく大きなチャンクを読み取るこの動作により、パフォーマンスが向上します。
  3. つまり、リーダーをバッファリングされたリーダーでdontラップすると、1文字を読み取りたいときに、disk.networkにアクセスして必要な1文字だけを取得します。このような小さなチャンクでI/Oを実行すると、通常、パフォーマンスが低下します。
5
radai