java nio之Buffer(一)
Buffer是一个包装了基本数据元素数组的对象,它以及它的子类定义了一系列API用于处理数据缓存。
一、属性
Buffer有四个基本属性:
1、capacity 容量,buffer能够容纳的最大元素数目,在Buffer创建时设定并不能更改
2、limit buffer中有效位置数目
3、position 下一个读或者写的位置
4、mark 用于记忆的标志位,配合reset()使用,初始值未设定,调用mark后将当前position设为值
四者关系:0 <= mark <= position <= limit <= capacity
二、API
public abstract class Buffer {
public final int capacity( )
public final int position( )
public final Buffer position (int newPosition)
public final int limit( )
public final Buffer limit (int newLimit)
public final Buffer mark( )
public final Buffer reset( )
public final Buffer clear( )
public final Buffer flip( )
public final Buffer rewind( )
public final int remaining( )
public final boolean hasRemaining( )
public abstract boolean isReadOnly( );
}
支持链式调用,如:buffer.mark().position(5).reset( );
注意isReadOnly()方法决定了buffer是否可写。
三、操作
以ByteBuffer为例,
1、访问,通过get(),get(index),其中get()从当前position位置读取,get(index)从index位置读取,不改变当前position,下面要说到的put也一样。
2、填充,通过put(byte),put(index,byte),按照绝对位置填充也是不改变当前position属性
3、flipping,试想,我们将填充完毕的buffer传递给socket输出,那么socket读取是依据position属性确定,就会从结尾后一位开始读,这样肯定是不正确的,如果要正确的读取我们先要:
buffer.limit(buffer.position( )).position(0);
将limit设为position, 将position设为0,这个操作就叫flipping,API直接提供了这个操作:
buffer.flip( );
特别注意,flip()方法会改变limit属性,将limit属性从capacity设置为当前position。rewind()方法与flip()类似,但是仅将position设为0,而不改变limit,通常用于重新读取已经被flip的buffer。flip()另一个注意点是,两次调用buffer的flip方法,将使得position和limit属性都为0。
4、迭代取元素:
myByteArray [i] = buffer.get( );
}
int count = buffer.remaining( );
for (int i = 0; i < count, i++) {
myByteArray [i] = buffer.get( );
}
ByteBuffer不是线程安全的,前一种方式适合并发访问,后一种方式效率更高。这两种方式都是一个一个取,效率都比批量取低。
5.clear()方法,将buffer重设为空状态,也就是设置limit=capacity,position=0,以便重复利用。
6.compact()方法,用于压缩buffer,这个方法在多次重复调用时是比较低效。
7.mark(),初始是未定义的,这适合如果调用reset将抛出InvalidMarkException。调用makr()后,将当前position设为mark以便reset时返回。注意,rewind( ), clear( ), and flip( )方法都将丢弃已经创建的mark。调用limit(index),positioon(index),如果index的值小于当前mark,mark也将被丢弃。
8.比较,可以通过equals()和compateTo()方法来比较两个buffer,前一个返回boolean,后一个返回0,-1,1。两个buffer equal的条件是:
1)类型相同
2)剩余元素的数目相等
3)剩余元素也一一相等
9、批量移动数据,为了更有效地进行数据传送,批量的数据存取肯定是不能少的,Buffer及其子类都有提供类似的方法,比如CharBuffer:
public CharBuffer get (char [] dst, int offset, int length)
public final CharBuffer put (char[] src)
public CharBuffer put (char [] src, int offset, int length)
public CharBuffer put (CharBuffer src)
public final CharBuffer put (String src)
public CharBuffer put (String src, int start, int end)
四、创建Buffer
Buffer以及其子类都无法直接new,而必须把通过他们提供的工厂方法来创建。通常有两种方式:
1、allocate,例如
CharBuffer charBuffer = CharBuffer.allocate (100);
将在堆上分配一个可以存储100个字符的数组作为backing store。
2、wrap,包装一个已有的数组:
char [] myArray = new char [100];
CharBuffer charbuffer = CharBuffer.wrap (myArray);
注意,这样的方式创建的Buffer,将不会在堆上创建新的数组,而是直接利用myArray做backing store,这意味着任何对myArray或者buffer的修改都将影响到buffer或者myArray。可以通过public final boolean hasArray(
)方法来判断是否拥有一个数组,通过array()方法取得这个数组。
五、复制Buffer
其实这个复制也是“浅拷贝”,通过duplicate()方法将返回一个新创建的buffer,这个新buffer与原来的Buffer共享数据,一样的capacity,但是有自己的position、limit和mark属性。通过asReadOnlyBuffer()方法复制的buffer与duplicate()类似,但是是只读的,不能调用put。比较特别的是slice()方法,故名思议,类似切割一个Buffer出来,与duplicate类似,但是它将从原来Buffer的当前position开始,并且capacity等于原来Buffer的剩余元素数目,也就是(limit-position)。
java nio之Buffer(一)的更多相关文章
- Java NIO 之 Buffer
Java NIO 之 Buffer Java NIO (Non Blocking IO 或者 New IO)是一种非阻塞IO的实现.NIO通过Channel.Buffer.Selector几个组件的协 ...
- Java NIO之Buffer(缓冲区)
Java NIO中的缓存区(Buffer)用于和通道(Channel)进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这 ...
- JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁
IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...
- Java NIO -- 缓冲区(Buffer)的数据存取
缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...
- Java NIO 之 Buffer(缓冲区)
一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...
- 【Java nio】buffer
package com.slp.nio; import org.junit.Test; import java.nio.ByteBuffer; /** * Created by sanglp on 2 ...
- java nio之Buffer
一.JAVA NIO 是在和channel交互的时候使用的.Channel将数据读入缓冲区,然后我们又从缓冲区访问数据.写数据时,首先将要发送的数据按顺序填入缓冲区.基本上,缓冲区只是一个列表,它的所 ...
- Java NIO:Buffer、Channel 和 Selector
Buffer 一个 Buffer 本质上是内存中的一块,我们可以将数据写入这块内存,之后从这块内存获取数据. java.nio 定义了以下几个 Buffer 的实现,这个图读者应该也在不少地方见过了吧 ...
- JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法
参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...
随机推荐
- cli下的php(并传递参数)
传递参数有两种方式: 第一种使用文件操作,STDOUT作为标准输出,STDIN作为标准输入 使用fwrite($file,$string)作输出,使用fgets($file)作输入.这种应该算是继承自 ...
- 【java版坦克大战---准备篇】 java 绘图
要写坦克大战当然要先画出坦克.java画图是基础. package com.game; import java.awt.*; import javax.swing.*; public class Pr ...
- Linux调整SWAP分区
刪除原swap分區,重建swap,步驟如下:1,swapoff -a #停止交換分區2,fdisk /dev/sda #進入fdisk,刪除原swap分區,重新建立新分區(swap分區的系統ID是82 ...
- [转]ef获取某个表中的部分字段值
我有个新闻表 id,title,body,createtime,author,click 使用ef4.1 仅仅读取 id,title,createtime 并显示在页面上. public static ...
- 基于h5+ajax实现的手机定位
因朋友需要,之前看了下关于h5的手机定位,目前写了个demo在这里贴出来,感兴趣的朋友可以看一下. 目前的版本只是demo,仍有几个问题需要完善一下,问题如下: 1,如何将经纬度等数据发送到被定位人看 ...
- 【UVA1331】关于最优三角剖分
最近在练习DP专题,学会了很多表示方法和转换方法,今天做最优三角剖分的时候发现脑子卡了,不会表示状态,于是写个博客记录一下. 最优三角剖分的一类题目都是差不多的.给你一个多边形,让你把它分割成若干个三 ...
- [转贴]Linq之动态查询
最近写Linq碰到一个问题, 就是如果要写一个查询系统,这个系统里面有很多TextBox可以填, 然后捞出符合各个字段的数据. 在SQL查询的时候还满方便的,用字符串连连连就可以了, ( 也就是sql ...
- Trace和Debug主要用法
#region 日志记录 //System.Diagnostics.Trace.Listeners.Clear(); //System.Diagnostics.Trace.AutoFlush = tr ...
- C++ Prime:const的引用
可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称之为对常量的引用.与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象: ; const int &r1 = ci; ...
- bzoj2553
似乎挂精度了,不过这是一道好题 很明显看题知算法,知道这道题肯定是AC自动机上矩阵乘法 首先要明确一点,对一个字符串,怎样划分禁忌串最多 根据求最多不相交线段可知,从头到尾能划分出禁忌串就划分 根据这 ...