Java I / Oで「ストリーム」と「バッファ」は正確にはどういう意味ですか?


82

を使用して入出力について学習しましたBufferedReader

私は正確に用語の意味が何であるかを知りたいと思ったStreamBuffer

また、このコード行は何に役立ちますか?

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

回答:


201

Javaには、入出力(I / O)用の2種類のクラスがあります。ストリームリーダー/ライターです。

ストリーム(InputStreamOutputStreamおよびこれらを拡張するすべてのもの)は、ファイル、ネットワーク、またはその他のデバイスからバイナリデータを読み書きするためのものです。

リーダーとライターは、テキスト(文字)を読み書きするためのものです。これらはストリームの上のレイヤーであり、文字エンコードを使用してバイナリデータ(バイト)を文字に変換し、その逆に変換します。

ディスクからバイトごとにデータを読み取ることは非常に非効率的です。これを高速化する1つの方法は、バッファーを使用することです。一度に1バイトを読み取る代わりに、一度に数千バイトを読み取り、それらをメモリー内のバッファーに入れます。次に、バッファ内のバイトを1つずつ確認できます。

I / Oに関するOracleのJavaチュートリアルでは、詳細に説明されています。

指定したコード行を見てください。

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

System.inですInputStreamInputStreamReaderからバイトを読み取るを作成しますSystem.in。次に、それをでラップしますBufferedReader

したがって、最終的には、BufferedReaderから読み取る、からInputStreamReader読み取るがありSystem.inます。


1
回答ありがとうございますが、混乱があります。一度に数千バイトを読み取ってバッファに入れるとおっしゃっていましたが、これはバッファがメモリ内の物を格納する場所にすぎないことを意味しますか?
user122345656 2013

3
@Jesper。「速度を上げる1つの方法は、バッファを使用することです。一度に1バイトを読み取る代わりに、一度に数千バイトを読み取り、それらをメモリ内のバッファに入れます。次に、バイトを確認できます。バッファに1つずつ。」はい、その通りですが、バッファでも一度に1バイトが読み取られると思います。唯一の違いは、バッファとプログラムに入れられ、ディスクではなくバッファから読み取られると思います
M Sach 2013

7
@ user122345656はい、バッファは一時的にデータを保存するためのメモリ内の場所です。
ジェスパー

14
@MSachハードディスクからデータを読み取りたいときに何が起こるか考えてみてください。特定の場所でバイトを読み取るには、ディスクが回転するまで、ヘッドが読み取られるバイトがあるディスク上の場所より上になるまで待つ必要があります。その時点で1バイトだけを読み取り、次のバイトを後で読み取る場合、次のバイトを読み取るには、ディスクが完全に回転するまで待つ必要があります。連続するバイトのブロックを読み取る方がはるかに効率的です。
ジェスパー

2
@parsecerストリームはバイトを読み取るためのものです。リーダーはテキスト(文字)を読むためのものです。InputStreamReaderは、InputStreamからテキストを読み取ることができるラッパーですInputStream。(文字ではなく)バイトを読み取りたいだけの場合は、は必要ありませんInputStreamReader。バイトをテキスト文字として解釈する場合に便利です。
ジェスパー

19

バッファ:

これは、ある場所から別の場所に移動するときにデータを一時的に保存するために使用される物理メモリストレージの領域です。その物理メモリストレージほとんどの場合、はRAM(ランダムアクセスメモリ)になります。

しかし、この質問の文脈から、 データの読み取り/書き込み中バッファが使用されます。ある場所から別の場所にデータを移動するときに使用する必要はありません。

バッファの例:システムに4 GBのRAMがある場合、システムによって4 KBのメモリ(RAM)がバッファに割り当てられる可能性があります。KB-キロバイト、GB-ギガバイト

I / Oストリーム(または)ストリーム:

I / Oストリームは、入力ソースまたは出力宛先を表します。ストリームは、ディスクファイル、デバイス、その他のプログラム、メモリアレイなど、さまざまな種類のソースと宛先を表すことができます。

I / Oは入力/出力を意味します。

したがって、入力ストリームは、ディスクファイル、ネットワーク接続などの入力ソースにすることができます。

また、出力ストリームは、ディスクファイル、ネットワーク接続などの出力先にすることができます。

JAVAの公式ドキュメントによると、ストリームには3つのタイプがあります。

  1. バイトストリームバイトの読み取りまたは書き込み)
  2. 文字ストリーム文字の読み取りまたは書き込み)
  3. バッファリングされたストリーム(効率のためにバッファからの読み取りまたはバッファへの書き込み)

バイトストリーム:

8ビットバイトの入出力を行います。すべてのバイトストリームクラスは、InputStreamおよびOutputStreamの子孫です。

バイト入力ストリームクラスは、入力を生のバイトとして取得します。バイト出力ストリームクラスは、生のバイトとして出力を提供します

InputStream-直接既知のサブクラス

AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream.

OutputStream-直接既知のサブクラス

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

キャラクターストリーム: バイトストリームの上にあるレイヤーです。文字エンコードを使用して、バイト(バイナリデータ)を文字に変換し、文字をバイトに変換します。

すべての文字ストリームクラスは、ReaderWriterの子孫です。

Reader -直接既知のサブクラス

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Writer -直接既知のサブクラス

BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

バイトストリームと文字ストリームは、バッファなしのI / Oを使用します。

これは、各読み取りまたは書き込み要求が基盤となるOSによって直接処理されることを意味します。このような要求はそれぞれ、ディスクアクセス、ネットワークアクティビティ、または比較的コストのかかるその他の操作をトリガーすることが多いため、これによりプログラムの効率が大幅に低下する可能性があります。この種のオーバーヘッドを減らすために、JavaプラットフォームはバッファリングされたI / Oストリームを実装します。

バッファリングされたストリーム:

バッファリングされた入力ストリームバッファと呼ばれるメモリ領域からデータを読み取ります。ネイティブ入力APIは、バッファーが空の場合にのみ呼び出されます。

同様に、バッファリングされた出力ストリームはデータをバッファに書き込み、ネイティブ出力APIはバッファがいっぱいになったときにのみ呼び出されます。

プログラムは、ラッピングイディオムを使用して、バッファリングされていないストリームをバッファリングされたストリームに変換できます。このイディオムでは、バッファリングされていないストリームオブジェクトがバッファリングされたコンストラクタに渡されます。ストリームクラスのます。

例:

inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));

バッファなしストリームをラップするために使用される4つのバッファ付きストリームクラスがあります。

作成するには、バッファ のバイトストリームを使用し、BufferedInputStreamかつBufferedOutputStreamクラスをます。

バッファリングされた 文字ストリームを作成するには、BufferedReaderおよびBufferedWriterクラスを使用します。


1
私はjavaioのそのような詳細な説明を探していました。どうもありがとうございました。
アリフレザ2018年

14

さて、java.ioパッケージで作業を開始する人は誰でも気になります。質問の用語に答えるために、InputStreamReaderとBufferedReaderはJavaオブジェクトのみを表します(それらについて特別なことは何もありません)が、ファイル、オブジェクトなどのさまざまな入力/出力との間の読み取りおよび書き込みなどのio操作用に作成されます

さあ、行こう

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

InputStreamReaderは、バイトの入力ストリームを読み取るクラスですが、各バイトを読み取るにはコストのかかる操作であるため、BufferedReaderをラップしてバッファリングします(デコレータパターン)。

したがって、読み取りを開始する前でも、bufferedReaderはバイトのチャンクをレジスタに格納し、読み取り操作を実行すると発生します。コンソール/ファイルから読み取るよりもはるかに安価なその場所から読み取られますが、InputStreamReaderの場合、ディスクアクセス操作が行われるたびに読み取り操作を実行すると


+1ですが、情報デコレータのリンク参照を追加し、ディスクアクセス操作が行われるたびにセンテンスを追加したいのですが
shareef

その最後の段落は、利点をうまく要約しています。有難うございます。
Dave Voyles 2015年

3

ストリームは、ポイント間で渡される接続と実際の情報です。バッファは、ストリーミングされたデータの一部またはすべてを格納し、これを出力デバイスに供給するストレージコンテナです。

もちろん、重要なのは、ストリームがデータの表示に必要なデータレートを超えて遅くなると、出力が一時停止するということです。バッファはこれを防ぎます。


回答ありがとうございますが、私の頭に浮かんだ質問は、ストリーミングデータとはどういう意味ですか?Plzはこれを詳しく説明しています。
user122345656 2013

1
返事が遅れて申し訳ありません。サーバー上の10Mbファイルの簡単な例を想像してみてください。サーバーには完全なファイルがありますが、ファイル全体を1つのパケットで送信することはできません。代わりに、ファイルは有限数のブロックに分割されます。次に、各ブロックがリモートコンピュータに送信され、再構築されます。ライブデータのストリーミングについても、同じ理論が当てはまります。ただし、サーバーはライブデータを取得し、それstreamをパケットとして送信します。次に、リモートコンピュータは各パケットをバッファに保存します。リモートコンピュータはそのバッファからデータを読み取り、これからビデオを作成します。これがお役に立てば幸いです。
PGallagher 2013

1

バッファは、周辺機器からのデータのストリームを格納するために使用されるメモリ内の部分です。次に、このバッファーからこのデータストリームが収集され、変数に格納されます。ストリームは、データの連続フローとして定義できます。

「入力/出力」という用語は、データをバッファに出し入れすることを意味します。これを常に心に留めておいてください。プロセスは、オペレーティングシステムに、バッファからデータを排出するか(書き込み操作)、またはバッファにデータを入力するか(読み取り操作)を要求することにより、I / Oを実行します。
データがどのように移動するかの論理図

簡単に言うと、キーボードでデータを入力すると、データがパイプ(ストリーム)を通ってバッファに移動し、次にバッファからディスクに移動する(書き込み操作)と想像してください。同様に、データがディスクからバッファに移動し、バッファからコンソールに移動すると、読み取り操作になります。

あなたはより良い理解のためにリンクを読むことができます。それが役に立てば幸い!。
Javaのバッファとは
ここにリンクの説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.