Scatter/Gather I/O
Scatter/Gather I/Oは、翻訳すると分散/集約I/O(Vectord I/Oとも呼ばれる)です.1回の呼び出しで複数のバッファを入出力できる方式であり、複数のバッファデータを一度にデータストリームに書き込むこともできるし、1つのデータストリームを複数のバッファに読み出すこともできる
Scatter/Gather I/Oを使用する主な理由は、1回のI/O操作で複数のBufferの読み書きを処理できるためである
各種オペレーティングシステムにはScatter/Gather I/Oの関数ライブラリが用意されており、簡単に呼び出すことができます.いくつかの高度な言語についても、それに対応して実現されています.
Javaでの実装
JavaではScatter/Gather I/Oの実装も提供されており、対応するインタフェースは
まずインタフェース定義を見てみましょう.
Javaでの使用例
次の例では、2つのByteBuyfferが作成され、1つのByteBufferはランダム数を格納し、もう1つのByteBufferはランダム文字列を格納します.
第1ステップでは、2つのByteBufferのデータを
第2部では、2つのByteBufferにFileChannelのデータを
ステップ3では、読み出したデータが一致しているかどうかを確認します.
サンプルコードソース:https://howtodoinjava.com/java/nio/nio-scatter-gather-vectored-io/
Nettyの実現??
NettyにはCompositeByteBufが提供されており、Scatter/Gather I/Oに似ているように見えますが、JDKが持参したものとは全く別のもので、NettyはJavaレベルでBufferを組み合わせただけです
リファレンス Chapter 4. Advanced File I/O - 《Linux System Programming 2nd Edition by Robert Love》 https://en.wikipedia.org/wiki/Vectored_I/O?oldformat=true 分散/集積IO(scatter/gather)及びiovec構造体 Java NIO Vectored IO
Scatter/Gather I/Oを使用する主な理由は、1回のI/O操作で複数のBufferの読み書きを処理できるためである
各種オペレーティングシステムにはScatter/Gather I/Oの関数ライブラリが用意されており、簡単に呼び出すことができます.いくつかの高度な言語についても、それに対応して実現されています.
Javaでの実装
JavaではScatter/Gather I/Oの実装も提供されており、対応するインタフェースは
java.nio.channels.ScatteringByteChannel/java.nio.channels.GatheringByteChannel
でjavaのnioパッケージの下にある.まずインタフェース定義を見てみましょう.
public interface ScatteringByteChannel extends ReadableByteChannel
{
public long read (ByteBuffer [] dsts) throws IOException;
public long read (ByteBuffer [] dsts, int offset, int length) throws IOException;
}
public interface GatheringByteChannel extends WritableByteChannel
{
public long write(ByteBuffer[] srcs) throws IOException;
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
}
FileChannel/
`SocketChanel ,
FileChannel/SocketChanel`の場合はScatter/Gather I/Oをそのまま使用できるので、使用も簡単ですJavaでの使用例
次の例では、2つのByteBuyfferが作成され、1つのByteBufferはランダム数を格納し、もう1つのByteBufferはランダム文字列を格納します.
第1ステップでは、2つのByteBufferのデータを
GatheringByteChannel
`を使用して`FileChannelに書き込む第2部では、2つのByteBufferにFileChannelのデータを
ScatteringByteChannel
を用いて読み出すステップ3では、読み出したデータが一致しているかどうかを確認します.
サンプルコードソース:https://howtodoinjava.com/java/nio/nio-scatter-gather-vectored-io/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
public class ScatteringAndGatheringIOExample
{
public static void main(String params[])
{
String data = "Scattering and Gathering example shown in howtodoinjava.com";
gatherBytes(data);
scatterBytes();
}
/*
* gatherBytes() reads bytes from different buffers and writes to file
* channel. Note that it uses a single write for both the buffers.
*/
public static void gatherBytes(String data)
{
//First Buffer holds a random number
ByteBuffer bufferOne = ByteBuffer.allocate(4);
//Second Buffer holds data we want to write
ByteBuffer buffer2 = ByteBuffer.allocate(200);
//Writing Data sets to Buffer
bufferOne.asIntBuffer().put(13);
buffer2.asCharBuffer().put(data);
//Calls FileOutputStream(file).getChannel()
GatheringByteChannel gatherer = createChannelInstance("test.txt", true);
//Write data to file
try
{
gatherer.write(new ByteBuffer[] { bufferOne, buffer2 });
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*
* scatterBytes() read bytes from a file channel into a set of buffers. Note that
* it uses a single read for both the buffers.
*/
public static void scatterBytes()
{
//First Buffer holds a random number
ByteBuffer bufferOne = ByteBuffer.allocate(4);
//Second Buffer holds data we want to write
ByteBuffer bufferTwo = ByteBuffer.allocate(200);
//Calls FileInputStream(file).getChannel()
ScatteringByteChannel scatterer = createChannelInstance("test.txt", false);
try
{
//Reading from the channel
scatterer.read(new ByteBuffer[] { bufferOne, bufferTwo });
}
catch (Exception e)
{
e.printStackTrace();
}
//Read the buffers seperately
bufferOne.rewind();
bufferTwo.rewind();
int bufferOneContent = bufferOne.asIntBuffer().get();
String bufferTwoContent = bufferTwo.asCharBuffer().toString();
//Verify the content
System.out.println(bufferOneContent);
System.out.println(bufferTwoContent);
}
public static FileChannel createChannelInstance(String file, boolean isOutput)
{
FileChannel fc = null;
try
{
if (isOutput) {
fc = new FileOutputStream(file).getChannel();
} else {
fc = new FileInputStream(file).getChannel();
}
}
catch (Exception e) {
e.printStackTrace();
}
return fc;
}
}
Nettyの実現??
NettyにはCompositeByteBufが提供されており、Scatter/Gather I/Oに似ているように見えますが、JDKが持参したものとは全く別のもので、NettyはJavaレベルでBufferを組み合わせただけです
リファレンス