NIO之缓冲区(Buffer)的数据存取
缓冲区(Buffer)
一个用于特定基本数据类行的容器。有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类。
Java NIO中的Buffer主要用于与NIO通道进行交互,数据是从通道读入到缓冲区,从缓冲区写入通道中的。
Buffer就像一个数组,可以保存多个相同类型的数据。根据类型不同(boolean除外),有以下Buffer常用子类:
- ByteBuffer
- CharBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
上述Buffer类他们都采用相似的方法进行管理数据,只是各自管理的数据类型不同而已,都是通过以下方法获取一个Buffer对象:
static XxxBuffer allocate(int capacity)
创建一个容量为capacity的XxxBuffer对象。
Buffer中的重要概念
1)容量(capacity):表示Buffer最大数据容量,缓冲区容量不能为负,并且建立后不能修改。
2)限制(limit):第一个不应该读取或者写入的数据的索引,即位于limit后的数据不可以读写。缓冲区的限制不能为负,并且不能大于其容量(capacity)。
3)位置(position):下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制(limit)。
4)标记(mark)与重置(reset):标记是一个索引,通过Buffer中的mark()方法指定Buffer中一个特定的position,之后可以通过调用reset()方法恢复到这个position。
注意:0<=mark<=position<=limit<=capacity
测试代码:
package com.dx.nios; import java.nio.ByteBuffer; import org.junit.Test; public class BufferTest { @Test
public void TestBuffer() {
ByteBuffer byteBuffer = ByteBuffer.allocate(10); System.out.println("------------allocate------------------");
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); byteBuffer.put("abcde".getBytes()); System.out.println("------------put------------------");
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); byteBuffer.flip(); System.out.println("------------flip------------------");
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); }
}
输出结果:
------------allocate------------------
10
------------put------------------
10
------------flip------------------
5
分析:
Buffer常用函数介绍及测试
clear()方法
clear()方法用于写模式,其作用为情况Buffer中的内容,所谓清空是指写上限与Buffer的真实容量相同,即limit==capacity,同时将当前写位置置为最前端下标为0处。代码如下:
public final Buffer clear() {
position = 0; //设置当前下标为0
limit = capacity; //设置写越界位置与和Buffer容量相同
mark = -1; //取消标记
return this;
}
rewind()方法
rewind()在读写模式下都可用,它单纯的将当前位置置0,同时取消mark标记,仅此而已;也就是说写模式下limit仍保持与Buffer容量相同,只是重头写而已;读模式下limit仍然与rewind()调用之前相同,也就是为flip()调用之前写模式下的position的最后位置,flip()调用后此位置变为了读模式的limit位置,即越界位置,代码如下:
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
flip()方法
flip()函数的作用是将写模式转变为读模式,即将写模式下的Buffer中内容的最后位置变为读模式下的limit位置,作为读越界位置,同时将当前读位置置为0,表示转换后重头开始读,同时再消除写模式下的mark标记,代码如下
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
测试
package com.dx.nios; import java.nio.ByteBuffer; import org.junit.Test; public class BufferTest { @Test
public void TestBuffer() {
// 1.使用allocate()申请10个字节的缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("------------allocate------------------");
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); // 2.使用put()存放5个字节到缓冲区
byteBuffer.put("abcde".getBytes());
System.out.println("------------put------------------");
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); // 3.切换到读取数据模式
byteBuffer.flip();
System.out.println("------------flip------------------");
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); // 4.从缓冲区中读取数据
System.out.println("------------get------------------");
byte[] bytes = new byte[byteBuffer.limit()];
byteBuffer.get(bytes);
System.out.println(new String(bytes, 0, bytes.length));
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); // 5.设置为可重复读取
System.out.println("------------rewind------------------");
byteBuffer.rewind();
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity());
byte[] bytes2 = new byte[byteBuffer.limit()];
byteBuffer.get(bytes2);
System.out.println(new String(bytes2, 0, bytes2.length));
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); // 6。clear清空缓存区,但是内容没有被清掉,还存在。只不过这些数据状态为被遗忘状态。
System.out.println("------------clear------------------");
byteBuffer.clear();
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity());
byte[] bytes3 = new byte[10];
byteBuffer.get(bytes3);
System.out.println(new String(bytes3, 0, bytes3.length));
}
}
输出:
------------allocate------------------
0
10
10
------------put------------------
5
10
10
------------flip------------------
0
5
10
------------get------------------
abcde
5
5
10
------------rewind------------------
0
5
10
abcde
5
5
10
------------clear------------------
0
10
10
abcde
mark与reset的用法
public static void main(String[] args){
ByteBuffer byteBuffer = ByteBuffer.allocate(1024); System.out.println("position:"+byteBuffer.position());
System.out.println("limit:"+byteBuffer.limit());
System.out.println("capcity"+byteBuffer.capacity());
System.out.println("--------------------------------"); String str = "从工单里来的状态";
for (int i = 0; i < 1; i++) {
str+="尚未完成";
} System.out.println("写入数据");
byteBuffer.put(str.getBytes()); System.out.println("position:"+byteBuffer.position());
System.out.println("limit:"+byteBuffer.limit());
System.out.println("capcity"+byteBuffer.capacity());
System.out.println("--------------------------------"); System.out.println("转换为读模式");
byteBuffer.flip(); byte[] bts = new byte[3];// byte数组设置的越大,一次就能放置更多的数据,但也不能太大,会影响传输,一般就是1024,这里故意设置小点为了测试
byteBuffer.get(bts);// 方法名容易让我误解,其实是把数据填充进byte数组 System.out.println("读取一个字符:"+new String(bts,0,bts.length)); System.out.println("position:"+byteBuffer.position());
System.out.println("limit:"+byteBuffer.limit());
System.out.println("capcity"+byteBuffer.capacity()); byteBuffer.get(bts);
System.out.println("再次读取一个字符:"+new String(bts,0,bts.length)); System.out.println("mark前");
System.out.println("position:"+byteBuffer.position());
System.out.println("limit:"+byteBuffer.limit());
System.out.println("capcity"+byteBuffer.capacity()); System.out.println("标记当前position位置");
byteBuffer.mark(); byteBuffer.get(bts);// 标记后,reset前再读取一次 System.out.println("mark后");
System.out.println("position:"+byteBuffer.position());
System.out.println("limit:"+byteBuffer.limit());
System.out.println("capcity"+byteBuffer.capacity()); System.out.println("恢复当前position位置为之前标记的位置");
byteBuffer.reset(); System.out.println("reset后");
System.out.println("position:"+byteBuffer.position());
System.out.println("limit:"+byteBuffer.limit());
System.out.println("capcity"+byteBuffer.capacity()); System.out.println("reset后的position应该和mark前的poisition相等");
System.out.println("--------------------------------"); }
打印信息:
position:0
limit:1024
capcity1024
--------------------------------
写入数据
position:36
limit:1024
capcity1024
--------------------------------
转换为读模式
读取一个字符:从
position:3
limit:36
capcity1024
再次读取一个字符:工
mark前
position:6
limit:36
capcity1024
标记当前position位置
mark后
position:9
limit:36
capcity1024
恢复当前position位置为之前标记的位置
reset后
position:6
limit:36
capcity1024
reset后的position应该和mark前的poisition相等
--------------------------------
NIO之缓冲区(Buffer)的数据存取的更多相关文章
- Java NIO -- 缓冲区(Buffer)的数据存取
缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...
- Java-NIO(二):缓冲区(Buffer)的数据存取
缓冲区(Buffer): 一个用于特定基本数据类行的容器.有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类. Java NIO中的Buffer主要用于与NIO通道进行交互,数据是从通 ...
- 缓冲区(Buffer)的数据存取
缓冲区(Buffer) 1. 缓冲区(Buffer):一个用于特定基本数据类 型的容器. 由 java.nio 包定义的,所有缓冲区 都是 Buffer 抽象类的子类.2. Java NIO 中的 B ...
- Java NIO之缓冲区Buffer
Java NIO的核心部件: Buffer Channel Selector Buffer 是一个数组,但具有内部状态.如下4个索引: capacity:总容量 position:下一个要读取/写入的 ...
- Buffer的数据存取
缓冲区 存放要读取的数据 缓冲区 和 通道 配合使用 一个用于特定基本数据类行的容器.有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类. Java NIO中的Buffer主要用于与N ...
- nio之缓冲区(Buffer)理解
一.缓冲区简介 Nio中的 Buffer 是用于存储特定基础类型的一个容器.为了能熟练的使用 Nio中的各种 Buffer , 我们需要理解 Buffer 中的 三个重要 的属性. 1. capaci ...
- Java NIO流 -- 缓冲区(Buffer,ByteBuffer)
用来定义缓冲区的所有类都以Buffer类为基类,Buffer定义了缓冲区的基本特征. 直接子类: ByteBuffer 用来存储byte类型的缓冲区,可以在这种缓冲区中存储任意其他基本类型的二进制值( ...
- NIO的缓冲区、通道、选择器关系理解
Buffer的数据存取 一个用于特定基本数据类行的容器.有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类. Java NIO中的Buffer主要用于与NIO通道进行交互,数 ...
- NIO(一)——缓冲区Buffer
NIO(一)--Buffer NIO简介 NIO即New IO,是用来代替标准IO的,提供了与标准IO完全不同传输方式. 核心: ...
随机推荐
- URAL 1682 Crazy Professor (并查集)
[题目链接] http://acm.timus.ru/problem.aspx?space=1&num=1682 [题目大意] 给出k,从1开始不断地加一并把这个数写在黑板上,如果写上的数字和 ...
- 【贪心】Codeforces Round #401 (Div. 2) D. Cloud of Hashtags
从后向前枚举字符串,然后从左向右枚举位. 如果该串的某位比之前的串的该位小,那么将之前的那串截断. 如果该串的某位比之前的串的该位大,那么之前那串可以直接保留全长度. 具体看代码. #include& ...
- 【计算几何】【极角序】【前缀和】bzoj1132 [POI2008]Tro
把点按纵坐标排序,依次枚举,把它作为原点,然后把之后的点极角排序,把叉积的公式稍微化简一下,处理个后缀和统计答案. #include<cstdio> #include<cmath&g ...
- 【点分治】poj1741 Tree / poj2114 Boatherds / poj1987 Distance Statistics
三道题都很类似.给出1741的代码 #include<cstdio> #include<algorithm> #include<cstring> using nam ...
- SciPy中两个模块:io 和misc
读写.mat文件 如果你有一些数据,或者在网上下载到一些有趣的数据集,这些数据以Matlab的.mat 文件格式存储,那么可以使用scipy.io 模块进行读取. data = scipy.io.lo ...
- 1.2(Spring学习笔记)Spring中的Bean
一.<Bean>的属性及子元素 在1.1中我们对<Bean>有了初步的认识,了解了一些基本用法. 现在我们进一步理解<Bean>属性及子元素. 我们先来看下< ...
- Java下String逗号数组和List<String>的互相转换
说明:很遗憾,组装的时候只能遍历. 方法: public static String listToString(List<String> list){ if(list==null){ re ...
- Delphi 使窗体Showmodal后可以操作其他窗体
对话框ShowModal之后不能操作其它窗口,实际上是因为Windows Disable了其它窗口.所以当你需要在模态对话框中访问其它已经可见的窗口时,需要用EnableWindow API来激活对应 ...
- springBoot框架的一些概念
Spring的发展史1. Spring1.x 时代 在Spring1.x时代,都是通过xml文件配置bean,随着项目的不断扩大,需要将xml配置分放到不同的配置文件中,需要频繁的在java类和xml ...
- 安装完office2016 64位后,在安装visio时,报错,无法安装,
安装环境要求: 系统要求:win8,win10等: office要求:sw(批量版)不能和cn(零售版).365版混装.-------重点注意事项 一定要注意批量版和零售版的区别,各版本之间绝对不允许 ...