原文出自:http://blog.csdn.net/lirx_tech/article/details/51396268

1. 通道映射技术:

1) 其实就是一种快速读写技术,它将通道所连接的数据节点中的全部或部分数据直接映射到内存的一个Buffer中,而这个内存Buffer块就是节点数据的映像,你直接对这个Buffer进行修改会直接影响到节点数据,而这个Buffer也不是普通的Buffer,叫做MappedBuffer,即镜像Buffer,对该Buffer进行修改会直接影响到实际的节点(更新到节点);

2) 由于是内存镜像,因此处理速度非常快!!

3) map原型:MappedByteBuffer map(MapMode mode, long position, long size);  // 将节点中从position开始的size个字节映射到返回的MappedByteBuffer中

4) mode印出来映射的三种模式,在这三种模式下得到的将是三种不同的MappedByteBuffer:三种模式都是Channel的内部类MapMode中定义的静态常量,这里以FileChannel举例

i. FileChannel.MapMode.READ_ONLY:得到的镜像只能读不能写(只能使用get之类的读取Buffer中的内容);

ii. FileChannel.MapMode.READ_WRITE:得到的镜像可读可写(既然可写了必然可读),对其写会直接更改到存储节点;

iii. FileChannel.MapMode.PRIVATE:得到一个私有的镜像,其实就是一个(position, size)区域的副本罢了,也是可读可写,只不过写不会影响到存储节点,就是一个普通的ByteBuffer了!!

5) 映射的规矩:

i. 使用InputStream获得的Channel可以映射,使用map时只能指定为READ_ONLY模式,不能指定为READ_WRITE和PRIVATE,否则会抛出运行时异常!

ii. 使用OutputStream得到的Channel不可以映射!!并且OutputStream的Channel也只能write不能read!

iii. 只有RandomAccessFile获取的Channel才能开启任意的这三种模式!

6) MappedByteBuffer的用法和普通的ByteBuffer一样,只不过它的功能被上述的映射规则所限制了,比如只读的就只能get不能put,可写的以及私有的put、get都能用;

7) 示例:只读映射

  1. public class Test {
  2. public static void main(String[] args) throws IOException {
  3. File f = new File("out.txt");
  4. try (
  5. FileChannel fcin = new FileInputStream(f).getChannel();
  6. FileChannel fcout = new FileOutputStream("a.txt").getChannel();
  7. ) {
  8. MappedByteBuffer mbb = fcin.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
  9. Charset cn = Charset.forName("GBK");
  10. System.out.println(cn.decode(mbb));
  11. mbb.flip(); // 写出去之前要操作就绪
  12. fcout.write(mbb);
  13. }
  14. }
  15. }

2. RandomAccessFile的通道映射可读可写:

1) RandomAccessFile也有getChannel方法获取相应的NIO通道;

2) 其实NIO通道映射技术最大的受益者就是RandomAccessFile了,因为RandomAccessFile本身就是可读可写I/O通吃,如果RandomAccessFile的节点文件映射到内存中,直接对内存镜像修改来更新文件节点那岂不是效率大大提高吗?

3) RandomAccessFile获取的通道同样是FileChannel,因此其使用上和之前讲过任何一个普通的Channel没有区别,映射map也是理所当然的一样;

4) 只不过其Channel在map时只读、读写、私有三种模式都可以使用,不像InputStream和OutputStream那样有种种约束;

!!只不过读写模式下,对内存镜像做出的修改会直接更新到节点文件!!

!!这里插播一个Channel常用的方法:long position(); // 获取当前操作到节点文件的哪个位置

5) 示例:将文件第一个字符改成“牛”,然后将改动好的整个文件内容复制一遍再追加到文件末尾!

  1. public class Test {
  2. public static void main(String[] args) throws IOException {
  3. File f = new File("out.txt");
  4. try (
  5. FileChannel fc = new RandomAccessFile(f, "rw").getChannel();
  6. ) {
  7. MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, f.length());
  8. mbb.put("牛".getBytes()); // 注意是字节,一定要转换成字节才行,这里对镜像的修改直接生效到节点文件中了!
  9. fc.position(f.length()); // 定位到文件末尾
  10. mbb.clear(); // 注意!一定要是clear,将limit定位到capacity!如果是flip则当前limit才在第二个字符位置!
  11. fc.write(mbb);
  12. }
  13. }
  14. }

!!注意:flip和clear要灵活运用,要根据他们的定义来(limit、position的变化);

(转)[疯狂Java]NIO:Channel的map映射的更多相关文章

  1. Java NIO Channel之FileChannel [ 转载 ]

    Java NIO Channel之FileChannel [ 转载 ] @author zachary.guo 对于文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许 ...

  2. Java NIO Channel和Buffer

    Java NIO Channel和Buffer @author ixenos Channel和Buffer的关系 1.NIO速度的提高来自于所使用的结构更接近于OS执行I/O的方式:通道和缓冲器: 2 ...

  3. Java NIO Channel通道

    原文链接:http://tutorials.jenkov.com/java-nio/channels.html Java NIO Channel通道和流非常相似,主要有以下几点区别: 通道可以读也可以 ...

  4. (三:NIO系列) Java NIO Channel

    出处: Java NIO Channel 1.1. Java NIO Channel的特点 和老的OIO相比,通道和NIO流(非阻塞IO)主要有以下几点区别: (1)OIO流一般来说是单向的(只能读或 ...

  5. [翻译] java NIO Channel

    原文地址:http://tutorials.jenkov.com/java-nio/channels.html JAVA NIO channels和流的概念很像,下面是他们的一些区别: 你可以对cha ...

  6. Java NIO Channel to Channel Transfers通道传输接口

    原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html 在Java NIO中如果一个channel是Fi ...

  7. Java NIO Channel to Channel Transfers

    In Java NIO you can transfer data directly from one channel to another, if one of the channels is a ...

  8. Java NIO Channel 使用

    Java NIO 中的 Channel 分类: FileChannel SocketChannel ServerSocketChannel DatagramChannel channel 分类 Fil ...

  9. 【JAVA】【NIO】3、Java NIO Channel

    Java NIO和流量相似,但有些差异: ·通道可读写,流仅支持单向.读或写 ·异步通道读取 ·通道读写器,他们是和Buffer交替 道的实现 下面是Java NIO中最重要的通道的实现: ·File ...

随机推荐

  1. 201521123074 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 Q1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现 ...

  2. Java:java中BufferedReader的read()及readLine()方法的使用心得

    BufferedReader的readLine()方法是阻塞式的, 如果到达流末尾, 就返回null, 但如果client的socket末经关闭就销毁, 则会产生IO异常. 正常的方法就是使用sock ...

  3. Apache Spark 2.2.0 中文文档 - 概述 | ApacheCN

    Spark 概述 Apache Spark 是一个快速的, 多用途的集群计算系统. 它提供了 Java, Scala, Python 和 R 的高级 API,以及一个支持通用的执行图计算的优化过的引擎 ...

  4. CDS测试框架介绍:如何为ABAP CDS Entities写测试

    动机 现在大家都知道单元测试对我们代码的好处.并且我们都承认它是开发过程中不可或缺的一部分.但是在把代码切换到数据库的模式下的时候,我们被粗暴地打回了软件测试的黑暗年代...我们现在面临着逻辑下推到A ...

  5. 百度富文本编辑器Ueditor使用

    首先我们登上ueditor下载,可以看到多种版本. UBuilder:可以自己选择需要的工具. 我用的开发版,Java的jsp版本,在这里是全部工具,但是工具在配置文件中也是可以自己选择的. 下载下来 ...

  6. Spring常用注解介绍【经典总结】

    Spring的一个核心功能是IOC,就是将Bean初始化加载到容器中,Bean是如何加载到容器的,可以使用Spring注解方式或者Spring XML配置方式. Spring注解方式减少了配置文件内容 ...

  7. TEXT宏

    TEXT宏是windows程序设计中经常遇到的宏,定义在 <winnt.h>中 TCHAR *P = TEXT("this is a const string"); 如 ...

  8. Sublimetext3安装Emmet插件步骤

    看清楚哦~~这是Sublime text 3不是2的版本,两者的安装还是有区别的,下面的方法是我感觉比较简单的,其他的要命令什么的感觉太复杂了,经测试是OK的. 先关闭Sublime text 3: ...

  9. Hbase 技术细节笔记(上)

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:张秀云 前言 最近在跟进Hbase的相关工作,由于之前对Hbase并不怎么了解,因此系统地学习了下Hbase,为了加深对Hbase的 ...

  10. 对Item中定时器的理解

    一.Diamond介绍 Diamond主要提供持久配置的发布和订阅服务,最大特点是结构简单,稳定可靠. 主要的使用场景:TDDL使用Diamond动态切换数据库,动态扩容等:业务使用Diamond推送 ...