文档章节

java NIO之Buffer基础

 王CHAO
发布于 2016/05/14 08:03
字数 1054
阅读 8
收藏 0

这段时间空闲下来,学习了下nio的一些东西,记录下来,以加深自己的理解和记忆。 

Java NIO 由以下几个核心部分组成: 

  • Channels
  • Buffers
  • Selectors


虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API。 
Buffers 缓冲区,以及缓冲区如何工作,是所有 I/O 的基础。所谓“输入/输出”讲的无非就是把数据移 进或移出缓冲区。 

概念:实际上缓冲区就是一个包含在对象里的基本数据元素数组 
属性:所有的缓冲区都具有四个属性来提供关于其所包含的数据元素的信息。它们是: 

  • 容量(Capacity) 缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变。
  • 上界(Limit) 缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
  • 位置(Position) 下一个要被读或写的元素的索引。位置会自动由相应的get( )和put( )函数更新。
  • 标记(Mark) 一个备忘位置。调用mark( )来设定mark = postion。调用reset( )设定position = mark。标记在设定前是未定义的(undefined)。

看下图 新创建一个ByteBuffer 

 

我们通过 ByteBuffer.allocate(11) 方法创建一个 10 个 byte 的数组缓冲区,初始状态如上图所示,position 的位置为 0,capacity 和 limit 默认都是数组长度。当我们写入 5 个字节时位置变化如下图所示: 

 


这时如果我们想在不丢失位置的情况下进行一些修改,比如说将hello更改为MelloW 
可以这样实现 
buffer.put(0,(byte)'M').put((byte)'w'); 
修改后的Buffer图像如下图 


 

如果我们想将缓冲区的 5 个字节数据写入 Channel 通信信道,我们需要调用 byteBuffer.flip() 方法,数组的状态又发生如下变化 

 


还有一个方法 rewind (),会重置position的位置为0 但不改变limit的位置,可以使用rewind()后退,重读已经被翻转的缓冲区中的数据。 

 

  • 一旦读完Buffer中的数据,需要让Buffer准备好再次被写入。可以通过clear()或compact()方法来完成。
  • 如果调用的是clear()方法,position将被设回0,limit被设置成 capacity的值。换句话说,Buffer 被清空了。但这个时候Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据。


看下面代码

Java代码 

 收藏代码

  1. public static void main(String[] argv) throws Exception {  
  2.         CharBuffer buffer = CharBuffer.allocate(20);  
  3.         System.out.println("初始化时候:position="+buffer.position()+" limit="+buffer.limit());  
  4.         fillBuffer(buffer,"hello");  
  5.         System.out.println("填入hello以后:position="+buffer.position()+" limit="+buffer.limit());  
  6.         buffer.put(0,'M').put('w');  
  7.         System.out.println("修改成Mellow后:position="+buffer.position()+" limit="+buffer.limit());  
  8.         buffer.flip();  
  9.         System.out.println("翻转后:position="+buffer.position()+" limit="+buffer.limit());  
  10.         buffer.clear();  
  11.         System.out.println("clear后:position="+buffer.position()+" limit="+buffer.limit());  
  12.         buffer.position(0);  
  13.         while (buffer.hasRemaining()) {  
  14.             System.out.println(buffer.get());  
  15.         }  
  16.     }private static void fillBuffer(CharBuffer buffer) {  
  17.         String string = "MY TEST BUFFER";  
  18.         for (int i = 0; i < string.length(); i++) {  
  19.             buffer.put(string.charAt(i));  
  20.         }  
  21.     }  
  22.   
  23. 结果:  
  24. 初始化时候:position=0 limit=20  
  25. 填入hello以后:position=5 limit=20  
  26. 修改成Mellow后:position=6 limit=20  
  27. 翻转后:position=0 limit=6  
  28. clear后:position=0 limit=20  
  29. M  
  30. e  
  31. l  
  32. l  
  33. o  
  34. w  


从上面例子可以看出clear后实际上buffer中数据还是存在的 
如果Buffer中有一些未读的数据,调用clear()方法,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有。 
如果Buffer中仍有未读的数据,且后续还需要这些数据,但是此时想要先先写些数据,那么使用compact()方法。 
看下面代码: 

Java代码 

 收藏代码

  1. public static void compactTest(){  
  2.         CharBuffer buffer = CharBuffer.allocate(11);  
  3.         fillBuffer(buffer,"hello world");  
  4.         buffer.position(6);  
  5.         buffer.compact();  
  6.         buffer.put("j");  
  7.         buffer.put("a");  
  8.         buffer.put("v");  
  9.         buffer.put("a");  
  10.         buffer.flip();  
  11.         while (buffer.hasRemaining()) {  
  12.             System.out.print(buffer.get());  
  13.         }  
  14.     }  
  15. 打印结果为worldjava  


compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。 
其它还有mark()与reset() equals()等方法 就不一一介绍了。 

© 著作权归作者所有

共有 人打赏支持
粉丝 0
博文 5
码字总数 3246
作品 0
东城
私信 提问
JAVA NIO编程入门(一)

JAVA NIO编程入门(一) 一、前言 笔者之前接触的NIO编程比较少,所以对这一块的基础也比较弱,NIO作为java编程中一个重要的模块,不能很好的掌握它,感觉自己在java方面就掌握的不够,所以,...

木木匠
09/01
0
0
Java NIO ByteBuffer学习

深入理解Apache Mina (6)---- Java Nio ByteBuffer与Mina ByteBuffer的区别 http://chinaestone.iteye.com/blog/468138 DirectBuffer及内存泄漏 http://blog.csdn.net/zhouhl_cn/article/d......

mj4738
2012/10/15
0
0
Java NIO 系列教程 -- delete

(一) Java NIO 概述 Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的A...

数据之美
2013/06/09
0
4
Java NIO系列教程(一) Java NIO 概述

Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API。其它组件,如Pipe和...

只想一个人静一静
2014/02/22
0
0
JAVA NIO(转)

Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。本系列教程将有助于你学习和理解Java NIO。感谢并发编程网的翻译和投递。 (关注ITeye官微,随时...

北极之北
2016/01/16
280
0

没有更多内容

加载失败,请刷新页面

加载更多

PHP生成CSV之内部换行

当我们使用PHP将采集到的文件内容保存到csv文件时,往往需要将采集内容进行二次过滤处理才能得到需要的内容。比如网页中的换行符,空格符等等。 对于空格等处理起来都比较简单,这里我们单独...

豆花饭烧土豆
今天
2
0
使用 mjml 生成 thymeleaf 邮件框架模板

发邮件算是系统开发的一个基本需求了,不过搞邮件模板实在是件恶心事,估计搞过的同仁都有体会。 得支持多种客户端 支持响应式 疼彻心扉的 outlook 多数客户端只支持 inline 形式的 css 布局...

郁也风
今天
8
0
让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字

让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字: 作者:孙冬梅;以前读韩国前总统朴槿惠的著作《绝望锻炼了我》时,里面有一句话令我印象深刻,她说“在我最困难的时期,...

原创小博客
今天
4
0
JAVA-四元数类

public class Quaternion { private final double x0, x1, x2, x3; // 四元数构造函数 public Quaternion(double x0, double x1, double x2, double x3) { this.x0 = ......

Pulsar-V
今天
18
0
Xshell利用Xftp传输文件,使用pure-ftpd搭建ftp服务

Xftp传输文件 如果已经通过Xshell登录到服务器,此时可以使用快捷键ctrl+alt+f 打开Xftp并展示Xshell当前的目录,之后直接拖拽传输文件即可。 pure-ftpd搭建ftp服务 pure-ftpd要比vsftp简单,...

野雪球
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部