注: Concurrent Programming Network、Java nio シリーズ チュートリアルから転載
Java NIO のバッファは、NIO チャネルと対話するために使用されます。ご存知のとおり、データはチャネルからバッファに読み取られ、バッファからチャネルに書き込まれます。
バッファは本質的に、データを書き込んだりそこからデータを読み取ったりできるメモリのブロックです。このメモリは NIO バッファ オブジェクトとしてパッケージ化されており、このメモリに簡単にアクセスするための一連のメソッドを提供します。
Buffer を使用してデータを読み書きするには、通常次の 4 つの手順に従います:
Buffer にデータを書き込む
flip()
メソッドを呼び出すflip()
方法
从Buffer中读取数据:如直接读取或读取到Channel中
调用clear()
方法或者compact()
clear()
メソッドまたは compact()
メソッドを呼び出します
バッファにデータを書き込むとき、バッファには書き込まれたデータの量が記録されます。データを読み取りたい場合は、flip() メソッドを通じてバッファを書き込みモードから読み取りモードに切り替える必要があります。読み取りモードでは、以前にバッファに書き込まれたすべてのデータを読み取ることができます。 すべてのデータが読み取られたら、再度書き込むことができるようにバッファをクリアする必要があります。バッファをクリアするには 2 つの方法があります。clear() メソッドまたは Compact() メソッドを呼び出すことです。 clear() メソッドはバッファ全体をクリアします。 Compact() メソッドは、読み取られたデータのみをクリアします。未読のデータはバッファの先頭に移動され、新しく書き込まれたデータはバッファ内の未読のデータの後に配置されます。 読み取りおよび書き込みモードの容量、位置、制限についての説明は図の後ろにあります。
capacity: 容量メモリブロックとして、Buffer には「容量」とも呼ばれる固定サイズの値があり、容量 byte、long、char およびその他の型のみを書き込むことができます。バッファがいっぱいになると、データの書き込みを続行する前に (データの読み取りまたはデータのクリアによって) バッファを空にする必要があります。 position: 現在位置バッファにデータを書き込むとき、position は現在位置を表します。初期位置値は 0 です。バイト、ロングなどのデータがバッファに書き込まれると、位置はデータを挿入できる次のバッファ ユニットに進みます。最大位置は容量 - 1 です。データを読み取るときは、特定の位置からも読み取られます。バッファが書き込みモードから読み取りモードに切り替わると、位置は 0 にリセットされます。データがバッファの位置から読み取られると、位置は次の読み取り可能な位置に進みます。 limit: 書き込み可能/読み取り可能な最大位置 書き込みモードでは、バッファの制限は、バッファに書き込むことができるデータの最大量を示します。 書き込みモードでは、制限はバッファの容量と同じになります。
ByteBuffer buf = ByteBuffer.allocate(50);
public void test1() throws FileNotFoundException {//初始化容量ByteBuffer buf1 = ByteBuffer.allocate(48);//通过数组初始化,并将数组中的值放入缓冲区byte[] bytes = "123".getBytes(); ByteBuffer buf2 = ByteBuffer.wrap(bytes);//将通道中的读到缓冲区int bytesRead = channel.read(bf);//通过put方法写入缓冲区,put有很多重载 buf1.put(bytes); }
put方法有很多版本,允许你以不同的方式把数据写入到Buffer中。例如, 写到一个指定的位置,或者把一个字节数组写入到Buffer。
flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。
换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。
从Buffer中读取数据有两种方式:
从Buffer读取数据到Channel。
使用get()方法从Buffer中读取数据。
//将缓冲区的数据写入通道 channel.write(buf1);//通过get方法获取缓冲区中数据 get有很多重载buf1.get();
get メソッドには多くのバージョンがあり、さまざまな方法でバッファからデータを読み取ることができます。たとえば、指定された位置から読み取るか、バッファからバイト配列にデータを読み取ります。
Buffer.rewind() は位置を 0 に戻すので、バッファー内のすべてのデータを再読み取りできます。制限は変更されず、バッファから読み取れる要素 (バイト、文字など) の数を示します。
バッファー内のデータが読み取られた後、バッファーを再び書き込む準備ができている必要があります。これは、clear() メソッドまたは Compact() メソッドを介して実行できます。
clear()メソッドが呼び出されると、positionは0に戻り、limitはcapacityの値に設定されます。つまり、バッファがクリアされます。バッファ内のデータはクリアされませんが、これらのマークは、バッファへのデータの書き込みを開始する場所を示します。
バッファーに未読のデータがある場合、clear() メソッドを呼び出します。データは「忘れられます」。つまり、どのデータが読み取られ、どのデータが読み取られていないのかを示すマーカーが存在しなくなります。
バッファ内にまだ読み取られていないデータがあり、そのデータが後で必要になるが、最初にデータを書き込みたい場合は、compact() メソッドを使用します。
compact() メソッドは、すべての未読データをバッファーの先頭にコピーします。次に、位置を最後の未読要素のすぐ後ろに設定します。制限属性は引き続き、clear() メソッドと同様に容量に設定されます。これでバッファはデータを書き込む準備が整いましたが、読み取られていないデータは上書きされません。
Buffer.mark() メソッドを呼び出すことで、バッファ内の特定の位置をマークできます。後で Buffer.reset() メソッドを呼び出すことで、この位置に復元できます。例:
2 つのバッファーを比較するには、equals() メソッドと CompareTo() メソッドを使用できます。
次の条件が満たされる場合、それは 2 つのバッファーが等しいことを意味します:
は同じ型 (byte、char、int など) を持ちます。
バッファ内の残りのバイト、文字などの数は等しい。
バッファ内の残りのバイト、文字などはすべて同じです。
ご覧のとおり、equals はバッファ内のすべての要素ではなく、バッファの一部のみを比較します。実際には、バッファ内の残りの要素を比較するだけです。
compareTo() メソッドは、2 つのバッファーの残りの要素 (byte、char など) を比較します。次の条件が満たされる場合、一方のバッファーは他方のバッファーより「小さい」とみなされます。
最初のものは、等しくない要素が別のバッファ内の対応する要素より小さいです。2. バッファーのスキャッター/ギャザー
いわゆるスキャッターとギャザーは複数のバッファーに対応するチャンネルです: 1 つのチャンネルを複数のバッファーに読み込みます。キャッシュ; 複数のキャッシュを 1 つのチャネルに書き込みます Java NIO は、スキャッター/ギャザリングをサポートし始めます。 チャネルからのスキャッタ読み取りとは、読み取り操作中に読み取りデータを複数のバッファに書き込むことを意味します。したがって、チャネルは、チャネルから読み取られたデータを複数のバッファに「分散」します。チャネルへの収集書き込みは、書き込み操作中に複数のバッファから同じチャネルにデータを書き込むことを意味します。それらをチャネルに送信します。 Scatter / Gather は、送信されるデータを個別に処理する必要がある場合によく使用されます。たとえば、メッセージ ヘッダーとメッセージ本文で構成されるメッセージを送信する場合、メッセージ本文とメッセージ ヘッダーを別のバッファーに分散することができます。これにより、メッセージ ヘッダーとメッセージ本文を簡単に処理できるようになります。 分散読み取り
分散読み取りとは、データが 1 つのチャネルから複数のバッファーに読み取られることを意味します。以下で説明します:
Java NIO: Scattering Read
以上がJAVAでのバッファの使用法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。