博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java NIO学习笔记 三 散点/收集 和频道转换
阅读量:5711 次
发布时间:2019-06-17

本文共 2440 字,大约阅读时间需要 8 分钟。

Java NIO散点/收集

  Java NIO带有内置的分散/收集支持。散点/收集是读取和写入渠道过程中使用的概念。

  从通道散射读取是将数据读入多个缓冲区的读取操作。因此,数据可以从通道“散布”到多个缓冲器中。

  对通道进行收集写入是将数据从多个缓冲区写入单个通道的写入操作。因此,数据可以从多个缓冲器收集到一个通道中。

  在需要分开处理传送数据的各个部分的情况下,散射/收集可能非常有用。例如,如果一个消息由header和body组成,那么就可以将头和body保存在单独的缓冲区中。这样会使您更容易单独使用标题和正文。

散射读取

  “散射读取”将数据从单个通道读入到多个缓冲器。

  这是一个原理的Scatter流程图:

Java NIO:散点阅读
Java NIO:散点读取

  这是一个代码示例,显示如何执行散射读取:

ByteBuffer header = ByteBuffer.allocate(128);ByteBuffer body = ByteBuffer.allocate(1024);ByteBuffer [] bufferArray = {header,body};channel.read(bufferArray);

  首先如何将缓冲区插入到数组中,然后将该数组作为参数传递给该channel.read()方法。read()方法然后按照缓冲区在数组中的顺序从通道写入数据。一旦缓冲区已满,通道将继续运行以填充下一个缓冲区。

  散射读取在移动到下一个之前填满一个缓冲区,这意味着它不适合于动态大小的消息部分。换句话说,如果你有一个标题和一个主体,并且标题是固定的大小(例如:128字节),那么散射读取工作正常。

收集写入

  “采集写入”将数据从多个缓冲区写入单个通道。

  流程图如下:

Java NIO:收集写
Java NIO:收集写

这是一个代码示例,显示如何执行收集写入:

ByteBuffer header = ByteBuffer.allocate(128);ByteBuffer body = ByteBuffer.allocate(1024);//将数据写入缓冲区ByteBuffer [] bufferArray = {header,body};channel.write(bufferArray);

  缓冲区的数组被传递到write()方法中,该方法按照它们在数组中的顺序依次向缓冲区写入内容。只写入缓冲区的位置和限制之间的数据。因此,如果缓冲器的容量为128字节,但只包含58字节,则只有58个字节从该缓冲区写入通道。因此,与散射读取相比,收集写入对于动态大小的信息可以正好工作。

 

Java NIO 频道到频道转接

  在Java NIO中,您可以将数据直接从一个通道传输到另一个通道。如果其中一个通道是FileChannel通道。这个FileChannel类有一个transferTo() 和transferFrom()方法可以完成这项操作。

transferFrom()方法

  FileChannel的transferFrom()方法将数据从源通道传输到 FileChannel

  以下简单的例子:

RandomAccessFile fromFile = new RandomAccessFile(“fromFile.txt”,“rw”);FileChannel fromChannel = fromFile.getChannel();RandomAccessFile toFile = new RandomAccessFile(“toFile.txt”,“rw”);FileChannel toChannel = toFile.getChannel();
long position= 0; long count = fromChannel.size(); toChannel.transferFrom(fromChannel,position,count);

  参数位置和数量,告诉目标文件中开始写入的位置(position),以及要最大传输(count)多少个字节。如果源通道的count字节少于传输的信道。

  另外,一些 SocketChannel实现方式可以只传输SocketChannel 在这里和现在的内部缓冲器已准备就绪的数据- 即使SocketChannel稍后可能有更多的数据可用。因此,它可能不会将所请求的整个数据(countSocketChannel传入FileChannel

transferTo()方法

  该transferTo()方法从一个FileChannel其他通道传输。

  简单的例子:

RandomAccessFile fromFile = new RandomAccessFile(“fromFile.txt”,“rw”);FileChannel fromChannel = fromFile.getChannel();RandomAccessFile toFile = new RandomAccessFile(“toFile.txt”,“rw”);FileChannel toChannel = toFile.getChannel();long position= 0;long count = fromChannel.size(); fromChannel.transferTo(position,count,toChannel);

  示例与上一个类似。唯一真正的区别是FileChannel调用该方法的对象。其余的是一样的。

该方法SocketChannel也存在问题transferTo()。该SocketChannel实现可能只从传输的字节FileChannel ,直到发送缓冲区已满,然后停止。

转载于:https://www.cnblogs.com/kuoAT/p/6999939.html

你可能感兴趣的文章
3. 指针的赋值
查看>>
linux小常识
查看>>
SQL中使用WITH AS提高性能 使用公用表表达式(CTE)简化嵌套SQL
查看>>
聊聊TaskExecutor的spring托管
查看>>
oracle 强行杀掉一个用户连接
查看>>
Git提交本地库代码到远程服务器的操作
查看>>
挨踢部落故事汇(13):扬长避短入行Oracle开发
查看>>
灾难拯救——让软件项目重回轨道
查看>>
ssh链接git服务器,解决push pull要求输入密码问题
查看>>
也说 Java 异常处理
查看>>
Netty 源码解析(二):对 Netty 中一些重要接口和类的介绍
查看>>
MAVEN spring boot 打包 和执行
查看>>
mysql中主外键关系
查看>>
第七章:数据字典
查看>>
python 字符串 类型互相转换 str bytes 字符串连接
查看>>
service mysqld start
查看>>
linux时间
查看>>
Spring+Mybatis项目中通过继承AbstractRoutingDataSource实现数据库热切换
查看>>
让Alert弹窗只弹出一次
查看>>
Berkeley DB 源代码分析 (1) --- 代码特征与游标的实现
查看>>