转自:http://blog.csdn.net/java2000_wl/article/details/7619395
1.Scatter 从一个Channel读取的信息分散到N个缓冲区中(Buufer).
2.Gather 将N个Buffer里面内容按照顺序发送到一个Channel.
Scatter/Gather功能是通道(Channel)提供的 并不是Buffer,
Scatter/Gather相关接口 类图
ReadableByteChannel WritableByteChannel 接口提供了通道的读写功能
ScatteringByteChannel GatheringByteChannel接口都新增了两个以缓冲区数组作为参数的相应方法
以FileChannel为例
*Scatter
- /**
- * Scatter
- * <br>------------------------------<br>
- * @param fileName
- * @throws IOException
- * @see FileChannel.read(java.nio.ByteBuffer[])
- */
- private static void scatter(final String fileName) throws IOException {
- RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");
- //获取文件通道
- FileChannel channel = accessFile.getChannel();
- //创建两个缓冲区
- ByteBuffer headBuffer = ByteBuffer.allocate(2);
- ByteBuffer bodyBuffer = ByteBuffer.allocate(1024);
- ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer};
- // headBuffer 前10个字节
- // bodyBuffer 剩下的
- long n = channel.read(allBuffers);
- System.out.println("共读到多少字节:" + n);
- headBuffer.flip();
- //head缓冲区中的数据:qw
- System.out.println("head缓冲区中的数据:" + charset.decode(headBuffer));
- bodyBuffer.flip();
- //body缓冲区中的数据:ertyuiop
- System.out.println("body缓冲区中的数据:" + charset.decode(bodyBuffer));
- accessFile.close();
- channel.close();
- }
- /**
- * Scatter2
- * <br>------------------------------<br>
- * @param fileName
- * @throws IOException
- * @see FileChannel.read(java.nio.ByteBuffer[], int, int)
- */
- private static void scatter2(final String fileName) throws IOException {
- RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");
- //获取文件通道
- FileChannel channel = accessFile.getChannel();
- //创建五个缓冲区
- ByteBuffer headBuffer = ByteBuffer.allocate(2);
- ByteBuffer bodyBuffer1 = ByteBuffer.allocate(3);
- ByteBuffer bodyBuffer2 = ByteBuffer.allocate(2);
- ByteBuffer bodyBuffer3 = ByteBuffer.allocate(2);
- ByteBuffer bodyBuffer4 = ByteBuffer.allocate(1);
- ByteBuffer[] allBuffers = new ByteBuffer[]{
- headBuffer,
- bodyBuffer1, bodyBuffer2,
- bodyBuffer3, bodyBuffer4,};
- //0从那个缓冲区开始被使用 使用3个缓冲区
- //会使用 headBuffer,bodyBuffer1,bodyBuffer2
- long n = channel.read(allBuffers, 0, 3);
- System.out.println("共读到多少字节:" + n);
- headBuffer.flip();
- //head缓冲区中的数据:qw
- System.out.println("head缓冲区中的数据:" + charset.decode(headBuffer));
- bodyBuffer1.flip();
- //body1缓冲区中的数据:ert
- System.out.println("body1缓冲区中的数据:" + charset.decode(bodyBuffer1));
- bodyBuffer2.flip();
- //body2缓冲区中的数据:yu
- System.out.println("body2缓冲区中的数据:" + charset.decode(bodyBuffer2));
- bodyBuffer3.flip();
- //body3,没有数据
- System.out.println("body3缓冲区中的数据:" + charset.decode(bodyBuffer3));
- bodyBuffer4.flip();
- //body4没有数据
- System.out.println("body4缓冲区中的数据:" + charset.decode(bodyBuffer4));
- accessFile.close();
- channel.close();
- }
- /**
- *
- * <br>------------------------------<br>
- * @param fileName
- * @throws IOException
- */
- private static void writeData(final String fileName, String data) throws IOException {
- RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");
- accessFile.writeBytes(data);
- accessFile.close();
- }
- private static Charset charset = Charset.forName("GBK");
- public static void main(String[] args) throws IOException {
- final String fileName = "D:/test.log";
- //先写入10个字节数据 以便测试 scatter模式
- writeData(fileName, "qwertyuiop");
- /**----------Scatter------------*/
- //read(java.nio.ByteBuffer[])
- scatter(fileName);
- //read(java.nio.ByteBuffer[], int, int)
- scatter2(fileName);
- }
*Gather
- /**
- * gather
- * <br>------------------------------<br>
- * @param fileName
- * @throws IOException
- * @see FileChannel#write(java.nio.ByteBuffer[])
- */
- private static void gather(String fileName) throws IOException {
- RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");
- //获取文件通道
- FileChannel channel = accessFile.getChannel();
- //创建两个缓冲区
- ByteBuffer headBuffer = ByteBuffer.allocate(3);
- headBuffer.put("abc".getBytes());
- ByteBuffer bodyBuffer = ByteBuffer.allocate(1024);
- bodyBuffer.put("defg".getBytes());
- ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer};
- headBuffer.flip();
- bodyBuffer.flip();
- //将按allBuffers顺序 写入abcdefg
- long n = channel.write(allBuffers);
- System.out.println("共写入多少字节:" + n);
- accessFile.close();
- channel.close();
- }
- /**
- * gather2
- * <br>------------------------------<br>
- * @param fileName
- * @throws IOException
- * @see FileChannel#write(java.nio.ByteBuffer[], int, int)
- */
- private static void gather2(String fileName) throws IOException {
- RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");
- //获取文件通道
- FileChannel channel = accessFile.getChannel();
- //创建两个缓冲区
- ByteBuffer headBuffer = ByteBuffer.allocate(3);
- ByteBuffer bodyBuffer1 = ByteBuffer.allocate(4);
- ByteBuffer bodyBuffer2 = ByteBuffer.allocate(20);
- ByteBuffer bodyBuffer3 = ByteBuffer.allocate(20);
- ByteBuffer bodyBuffer4 = ByteBuffer.allocate(20);
- headBuffer.put("abc".getBytes());
- bodyBuffer1.put("defg".getBytes());
- bodyBuffer2.put("bnbnbnb".getBytes());
- bodyBuffer3.put("zzz444".getBytes());
- ByteBuffer[] allBuffers = new ByteBuffer[]{
- headBuffer,
- bodyBuffer1, bodyBuffer2,
- bodyBuffer3, bodyBuffer4,};
- headBuffer.flip();
- bodyBuffer1.flip();
- bodyBuffer2.flip();
- bodyBuffer3.flip();
- bodyBuffer4.flip();
- //将按allBuffers数组顺序使用两个缓冲区
- //0从哪开始
- //2使用几个
- //当前使用headBuffer bodyBuffer1
- //最终写入abcdefg
- long n = channel.write(allBuffers, 0, 2);
- //应该返回7个字节
- System.out.println("共写入多少字节:" + n);
- accessFile.close();
- channel.close();
- }
- private static Charset charset = Charset.forName("GBK");
- public static void main(String[] args) throws IOException {
- final String fileName = "D:/test.log";
- /**----------Gather------------*/
- //FileChannel#write(java.nio.ByteBuffer[])
- gather(fileName);
- //FileChannel#write(java.nio.ByteBuffer[], int, int)
- gather2(fileName);
- }
相关推荐
原文:《Java NIO Scatter / Gather》 Scatter(分散):将一个 Channel 中的数据读取到多个 Buffer 中。 Gather(聚集):将多个 Buffer 中的数据写入一个 Channel 中。 Scatter/Gather 机制可以方便处理多个分开的...
Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) FileChannel Java NIO系列教程(八) SocketChannel Java NIO系列教程...
7. **scatter/gather传输**:NIO支持scatter/gather传输,即数据可以从多个缓冲区写入通道,也可以从通道分散读取到多个缓冲区,这对于处理多个数据源和目标非常有用。 8. **管道(Pipe)**:NIO引入了管道,允许两个...
7. ** Scatter/Gather(分散/聚集)**:NIO支持Scatter/Gather读写,即可以从多个缓冲区分散读取数据,也可以向多个缓冲区聚集写入数据,这在处理大块数据时非常有用。 8. **内存映射文件(Memory-Mapped Files)**...
8. **scatter/gather I/O**:scatter/gather是指在一次操作中,可以从多个缓冲区读取数据(scatter),或者将数据写入到多个缓冲区(gather),提高了数据处理的效率。 9. **文件系统事件(WatchService)**:Java ...
yubo-java-nioNIO 直接缓冲区 VS 非直接缓冲区直接缓冲区1、直接... Scatter/Gather 应该与直接 ByteBuffer 一起使用,以从本机 I/O 中获得最大优势。Java 引用对象类型1、JCP java并发实践JCP AQS - 抽象排队同步器
- **scatter/gather I/O**:scatter/gather允许数据从多个缓冲区写入通道,或者从通道读取到多个缓冲区,提高了数据处理的灵活性。 Java NIO适用于高性能服务器端和客户端应用,例如在处理高并发连接的网络服务器中...
- Scatter/Gather:允许一个单一的缓冲区被分散(读时)到多个缓冲区,或从多个缓冲区集中(写时)到一个单一的缓冲区。 NIO的使用场景包括: - 大数据量文件处理,如文件拷贝和网络服务器。 - 与特定硬件设备交互...
在深入研究时,可以进一步探索通道的其他特性,如文件映射(Memory-Mapped File)、 scatter/gather 读写(scatter-read/gather-write)等高级功能。同时,结合使用缓冲区、选择器以及多线程和并发控制,能够设计出...
6. **scatter/gather I/O**:scatter/gather I/O允许数据从多个缓冲区读取或写入一个通道,或者从一个通道分散到多个缓冲区,这对于处理大数据或并发写入多个目标非常有用。 NIO的应用场景广泛,例如在网络编程中,...
此外,NIO还提供了scatter/gather读写功能,即数据可以从多个缓冲区写入通道,或者从通道分散读取到多个缓冲区,这对于处理大块数据非常有用。管道(Pipe)则提供了一个单向数据流,可以用于线程间通信。 总的来说...
- 散集(Scatter)是从一个通道分散地读取数据到多个缓冲区,而聚集(Gather)是从多个缓冲区聚合数据到一个通道。这种操作在处理多个小块数据时非常有用。 9. **文件锁定** - Java NIO提供了文件锁定功能,可以...
8. **聚合操作(Scatter/Gather)**:NIO支持数据的分散读取(Scatter)和聚集写入(Gather),即可以从多个缓冲区分散读取数据,也可以将数据聚集到多个缓冲区进行写入。 9. **文件锁(File Locking)**:NIO提供...
- **散列/收集 (Scatter/Gather)**:解释了如何使用 Channel 进行散列/收集操作,这是一种优化读写操作的技术。 - **FileChannel**:详细讨论了 FileChannel 的使用场景及其特点。 - **内存映射文件 (Memory-Mapped ...
教程可能还会深入讲解NIO的高级特性,如scatter/gather(分散/聚集)读写,以及如何使用`Selector`进行多路复用。通过学习这个教程,开发者可以更好地理解和掌握Java NIO,从而在实际项目中有效提升程序的性能和并发...
7. ** Scatter/Gather(分散/聚集)**:这是NIO提供的另一种高效I/O技术。通过scatter操作,可以从多个缓冲区分散读取数据;通过gather操作,可以将多个缓冲区的数据聚集写入。 在实际开发中,Java NIO常用于高并发...