1.1 NIO Buffers - Class java.nio.Buffer

NIO data transfer is through the so-called buffers implemented in java.nio.Buffer class. A Buffer is similar to an array, except that it's implemented much more efficiently by closely coupled with the underlying OS.A Buffer is a contiguous, linear storage. Similar to an array, a Buffer has a fixed capacity.

The Buffer class for each of the primitibe types(except boolean), as shown in the above diagram. The abstarct superclass java.nio.Buffer provides the common properties  and some common operatons of all buffers.

Buffer has a capacitypositionlimit, and an optional mark:

  • The capacity must be specified when the Buffer is constructed and cannot be changed (similar to an array). You can retrieve it via method capacity().
  • The limit specifies the current occupancy. In other word, the buffer contains valid data in the range 0 to limit-1. You can retrieve the current limit via method limit() or set the limit via methodlimit(int newLimit). Limit shall not be greater than capacity.
  • Unlike array, there is a so-called position (or cursor) in a Buffer that indicates where the next piece of data is to be read or written. You can retrieve the current position via method position() or change the current position via method position(int newPosition). Position shall not be greater than the limit.
  • mark provide a positional marker. You can mark the current position via the method mark().

Data Transfer (Get/Put):

Each of the primitive buffers provides a set of get() and put() methods to read/write an element or a array of elements from/to the buffer. The position increases by the number of elements transferred. For example, the IntBuffer provides:


ByteBuffer is special. It provides additional getXxx()/putXxx() methods to parse raw bytes into other primitive types. It also can be used as the sources and targets of I/O operations, which will be explained later in channel I/O.

Mark and Reset:

You can use mark() method to mark the current position. Invoking reset() sets the position to the previously-marked position. The mark may or may not be set. If the mark is not set, invoking reset() triggers an InvalidMarkException. If the mark is set, it should never be greater than the position (because the mark() marks the current position and position advances). The mark will be discarded when the position or the limit is adjusted to a value smaller than the mark. Hence, 0 ≤ mark ≤ position ≤ limit ≤ capacity.

Clear, Flip and Rewind: 

  • clear(): sets the position to 0, limit to the capacity, and discards mark. It prepares the buffer for input.
  • flip(): sets the limit to the current positionposition to 0, and discard mark. Buffer populated and ready for output.
  • rewind(): set the position to 0, and discard mark. It prepares the buffer for re-read.

Creating a Buffer: There are 3 ways to create a buffer:

  1. via method allocate(int capacity), which allocates a new buffer, sets position to 0 and limit to capacity, and clear the mark.
  2. wrap an existing array into buffer via wrap(type[] array, int offset, int length) or wrap(type[] array) method.
  3. by creating a view of an existing ByteBuffer (to be discussed later).

Slicing and data sharing:

The slice() method creates sub-buffer from an existing buffer. That is it creates a new buffer sharing a portion of the original buffer.

We can see a example:

Then we alter elements in the buffer(two buffers and the sub-buffers share the same underlying data array).

Here is the ouput:

before alter sub-buffer:0 1 2 3 4 5 6 7 8 9 
alter elements in sub buffer.
After altering sub buffer0 1 2 33 44 55 66 7 8 9

Read-only buffers

Read-only buffers means only read operation allowed. We can turn any regular buffer into a read-only buffer by calling its asReadOnlyBuffer() method, which returns a new buffer that is identical to the first (and shares data with it), but is read-only. But we can not turn an read-only buffer to writable buffer.

Direct and in Direct buffer

To see the difference between these two buffer, please see Analysis about different methods for reading and writing file in Java language.

Memory-mapped file I/O

Memory-mapped file I/O can read and write file more fast than regular stream or channel based I/O.

Memory-mapped file I/O is accomplished by causing the data in a file to magically appear as the contents of a memory array. For it provide access to the facility that OS implement FS by mapping portions of a file into portions of memory, doing so on demand.

Mapping a file into memory example:

    static void MappingFileMem() throws IOException{
String inFileStr = "/users/wsy/Documents/job/kimchi_v2.pdf";
String outFileStr = "./kimchi_v2.pdf";
long startTime, elapsedTime; // for speed benchmarking
int bufferSizeKB = 4;
int bufferSize = bufferSizeKB * 1024;
FileInputStream input = new FileInputStream(inFileStr);
FileChannel channel = input.getChannel(); MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
}

Scattering and gathering

Scatter/gather I/O is a method of reading and writing that uses multiple buffers, rather than a single buffer. A scatter read reads data into a array of buffers rather than a single buffer. A gathering write writes data from a array of buffers rather than a single buffer.

Applications of scatter/gather:

Scatter/gather I/O is useful for dividing a piece of data into sections. For example, we can write a networking app that uses message objects, and each messages divided into a fixed-length header and body We can create 2 buffers, one for the header, and other for the body.When we put these 2 in an array and read data into them by scattering read, then the header and body will be neatly divided into 2 buffers. The scatter read will automatically find the first with room in it. After the previous filled, it movs to the next one.

  • long read( ByteBuffer[] dsts );
  • long read( ByteBuffer[] dsts, int offset, int length );

Gathering writes is like the Scattering reads.

Java Buffer的更多相关文章

  1. Java学习笔记20(String类应用、StringBuffer类、StringBuilder类)

    1.获取指定字符串中大小写和数字的个数: package demo; public class StringTest { public static void main(String[] args) ...

  2. Java IO、NIO、AIO知识总结

    本文主要讲述下自己对IO的理解,对IO的用法和细则可能没有顾虑到. 本文的理解基于以下几篇文章,他们对各自部分都讲的很细,对我理解IO提供了很大帮助. https://www.cnblogs.com/ ...

  3. 【JAVA语法】01Java-变量与数据类型

    数据类型初阶 基本数据类型的包装类 整数类型&浮点类型&字符类型 大小类型转换 通过Scanner从控制台获取数据 变量相关基础算法 Java的错误类型 字符串String 补充-Pa ...

  4. java#tostring

    通常使用apache-commons 来生成tostring方法,但是对于类型为java.util.Date的字段打印效果并不是我们想要的. @Override public String toStr ...

  5. Android OpenGL ES(三)OpenGL ES API 命名习惯 .

    OpenGL ES是个跨平台的3D图形开发包规范,最常见的实现是采用C语言实现的,Android OpenGL ES 实现上是使用Java 语言对底层的C接口进行了封装,因此在android.open ...

  6. 代码生成器实现的Entity,Dao,Service,Controller,JSP神器(含代码附件)

    package com.flong.codegenerator; import java.sql.Connection; import java.sql.DatabaseMetaData; impor ...

  7. 11jsp

    1.JSP 1. 指令 作用:用于配置JSP页面,导入资源文件 格式:             <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %> 分类:        ...

  8. SprinfJdbcTemplate+SpringMVC 代码生成器实现的Entity,Dao,Service,Controller,JSP神器(含代码附件)

    代码生成器实现的Entity,Dao,Service,Controller,JSP神器(含代码附件) 原文地址: http://jilongliang.iteye.com/blog/2262070 p ...

  9. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

随机推荐

  1. MOSS2010部署解决方案失败是可以尝试更新

    update-spsolution -identity XXX.wsp -literalpath D:\SPS2010Setup\XXX.wsp -gacdeployment

  2. Oracle的总体回顾

    1.多表查询:一张以上的表进行查询,称为多表查询,多表查询的时候可以为表指定别名的方式以简化查询列的编写,在多表查询中,会产生笛卡尔积,就是两张表的总数相乘得到的结果,如果要想消除笛卡尔积要通过关联条 ...

  3. InterviewProblems

    package com.xiaoysec; /** * 下面是面试趣医网技术面的时候出现的一个简单的题目 题目的要求是将一个数组中的奇数和偶数进行分离 以奇数在前一部分为例进行解题 * 算法的主要思想 ...

  4. 如何设置MySQL数据库名、表名大小写敏感

    在 MySQL 中,数据库和表其实就是数据目录下的目录和文. 因而,操作系统的敏感性决定数据库和表命名的大小写敏感.这就意味着数据库和表名在 Windows 中是大小写不敏感的,而在大多数类型的 Un ...

  5. css background-position (图片裁取)

    语法:background-position : length || length background-position : position || position 取值:length  : 百分 ...

  6. jquery插件anccordion

    (function(){ $.fn.YAccordion=function(options){ var settings={ trigger:'click', speed:300, }; if(opt ...

  7. codeforces 645 D. Robot Rapping Results Report 二分+拓扑排序

    题目链接 我们可以发现, 这是一个很明显的二分+拓扑排序.... 如何判断根据当前的点, 是否能构造出来一个唯一的拓扑序列呢. 如果有的点没有出现, 那么一定不满足. 如果在加进队列的时候, 同时加了 ...

  8. 几种改变Activity回退栈默认行为的Intent Flag

    FLAG_与LaunchMode相比最大的不同是临时性 1.FLAG_ACTIVITY_NEW_TASK: Developer.android.com的说法: (1)在新的task中启动这个Activ ...

  9. linux的nohup命令的用法。

    在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会 用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /usr/local/mysql/bin/m ...

  10. 【Win7激活工具2013版下载】适用于旗舰版、家庭高级版等所有版本32/64位 OEM激活

    虽然现在Win8已经发布了,但是身边总是还有一些朋友在用着Win7系统,而近期微软频繁的推送补丁包,导致之前的那些激活都失效了.找了网络上很多工具,之前的那些有的已经不能用了,激活不了,今天就推荐一些 ...