原文出自: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. 201521123011《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. MySql数据库简单操作 1.启动与退出(quit或exit ) 操作 显示所有数据库: show databa ...

  2. 201521123016 《Java程序设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? ping w ...

  3. 201521123016《Java程序设计》第12周学习总结

    1. 本周学习总结 2. 书面作业 将Student对象(属性:int id, String name,int age,double grade)写入文件student.data.从文件读出显示. 1 ...

  4. 201521123014 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 1.关于异常上次作业已经概括得差不多了,创建自己的异常时可以使用Java类库中已经定义好的类,也可自定义异常 ...

  5. Markdown例子

    一个例子: 例子开始 1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一 ...

  6. Java:设计类的继承关系时的技巧

    继承设计的技巧: (1)将公共操作和域放置在超类 (2)不要使用受保护的域 有些程序员认为,将大多数的实例域定义为protected是一个不错的主意,只有这样,子类才能够在需要的时候直接访问他们.然而 ...

  7. Struts2第七篇【介绍拦截器、自定义拦截器、执行流程、应用】

    什么是拦截器 拦截器Interceptor-..拦截器是Struts的概念,它与过滤器是类似的-可以近似于看作是过滤器 为什么我们要使用拦截器 前面在介绍Struts的时候已经讲解过了,Struts为 ...

  8. [UIKit学习]00.关于前置知识(storyboard,UIViewController,类扩展,项目属性)

    storyboard文件的认识 用来描述软件界面 默认情况下,程序一启动就会加载Main.storyboard 加载storyboard时,会首先创建和显示箭头所指的控制器界面 IBAction和IB ...

  9. CSS的常用属性

    刚开始学习前段的我,还处于初级阶段,一些东西还是会有搞不明白的时候,还是要大家多多理解.今说就一些关于CSS的常用属性吧! 一.CSS常用选择器 CSS选择器应该说是一个非常重要的工具吧,选择器用得好 ...

  10. idea导出war包

    使用idea一个月了还没有用到导出war,今天突然需要我来部署测试war包,想使用myeclipse的,转念一想太掉价了 废话少说,直接上菜 如果你没有第一步操作我建议你配置一下你的idea 当然还有 ...