Buffer 有3个重要的参数:位置(position)、容量(capactiy)、上限(limit)
 位置(position): 写:当前缓冲区的位置,将从position的下一个位置写数据。 读:当前缓冲区的读取的位置,将从此位置后,读取数据。
 容量(capactiy): 写:缓冲区的总容量上限。 读:缓冲区的总容量上限。
 上限(limit): 写:缓冲区的实际上限,它总是小于等于容量。通常情况下,和容量相等。 读:代表可读取的总容量,和上次写入的数据量相等。

public static void main(String[] args) {
ByteBuffer b = ByteBuffer.allocate(15);//15字节大小的缓冲区
System.out.println(b);//[pos=0 lim=15 cap=15]
for (int i = 0; i < 10; i++) {
b.put((byte) i);//存入10字节数据
}
//pos=10 为下一个即将输入的位置
System.out.println(b); //[pos=10 lim=15 cap=15] b.flip();//重置position 通常将Buffer从写模式转换为读模式需要执行此方法
//flip()不仅重置了当前position为0,还将limt设置到当前的position的位置,
//这样做的目的是防止在读模式中,读到应用程序根本没有进行操作的区域。
System.out.println(b);//[pos=0 lim=10 cap=15] for (int i = 0; i < 5; i++) {
System.out.print(b.get()); //
}
System.out.println();
//执行5次读操作,和写操作一样,读操作也会将position设置到当前位置
System.out.println(b); //[pos=5 lim=10 cap=15] b.flip();
System.out.println(b);//[pos=0 lim=5 cap=15] ////////////////////////////////////////////////// /**
* 1.Buffer的创建
*/
//从堆中分配缓冲区
//ByteBuffer buffer = ByteBuffer.allocate(1024);
//从既有数组中创建
byte[] array = new byte[1024];
ByteBuffer buffer = ByteBuffer.wrap(array);
System.out.println("------------------------------------");
/**
* 2.重置和清空缓冲区
* 重置 :指重置了Buffer各项标志位,并不是真正清空了Buffer内容。
* 它的作用在于为提取Buffer的有效数据做准备。
*
* rewind() //将position置零,并清除标志位(mark)
* out.wirte(buf);//从Buffer读取数据到Channel
* buf.rewind(); //回滚Buffer
* buf.get(array); //将Buffer的有效数据复制到数组中。
*
* clear() //将position置零,同时将limit设置为capacity的大小,并清除了标志mark.
* 由于清空了limit 便无法得知Buffer内那些数据是真实有效的,这个方法用于为重新写Buffer做准备。
* buf.clear(); //为读入数据到Buffer做准备
* in.read(buf); //从通道读入数据
*
* flip() //将limit设置到position所在位置,然后将position置零,并清除标志位mark,通常在读写转换时使用。
* buf.put(magic); //将magic数组写入Buffer
* in.read(buf); //从通道读入给定数据,存放到Buffer中
* buf.flip(); //将Buffer从读状态转换为写状态
* out.write(buf); //将magic和in通道中读入数据,写到通道out中。
*/ /**
* 3.标志(mark)缓冲区
* 可以随时记录当前位置,然后在任意时刻回到这个位置,加快或简化数据处理流程
*
* mark() //记录当前位置。
* reset() //用于恢复到mark所在的位置。
*/ ByteBuffer bb= ByteBuffer.allocate(15);
for (int i = 0; i < 10; i++) {
bb.put((byte) i);
}
System.out.println(bb);
bb.flip();//准备读 for (int i = 0; i < bb.limit(); i++) {
System.out.print(bb.get());
if(i == 4){
bb.mark(); //在第四个位置做mark
System.out.println("\nmark at "+ i);
}
}
bb.reset();//回到mark位置 并处理后续数据
System.out.println("\nreset to mark"); while(bb.hasRemaining()){//后续所有数据将被处理
System.out.print(bb.get());
}
System.out.println(); System.out.println("----------------------------------"); /**
* 4.复制缓冲区
*
* duplicate() //以源缓冲区为基础,生成一个完全一样的新缓冲区,会共享相同的内存数据,任意一方数据改动都是相互可见的。
* 两者独立维护了各自的position、limit、mark.
*
*/
ByteBuffer b1 = ByteBuffer.allocate(15);
for (int i = 0; i < 10; i++) {
b1.put((byte) i);
} ByteBuffer cp = b1.duplicate();//复制当前缓冲区
System.out.println(b1); //[pos=10 lim=15 cap=15]
System.out.println(cp); //[pos=10 lim=15 cap=15] cp.flip(); //重置缓冲区cp System.out.println(b1); //[pos=10 lim=15 cap=15]
System.out.println(cp); //[pos=0 lim=10 cap=15] cp.put((byte) 100); //向缓冲区cp存入数据
//数据是共享的
System.out.println("b1="+b1.get(0)); //b1=100
System.out.println("cp="+cp.get(0)); //cp=100 System.out.println("-----------------------------------"); /**
* 5.缓冲区分片
*
* slice() //在现有缓冲区中,创建新的子缓冲区,子缓冲区和父缓冲区共享数据。
* 缓冲区切片可以将一个大缓冲区进行分割处理,得到的子缓冲区都具有完整的缓冲区模型结构
*/
ByteBuffer b2 = ByteBuffer.allocate(15);
for (int i = 0; i < 10; i++) {
b2.put((byte) i);
}
System.out.println(b2);
b2.position(2);
b2.limit(6);
ByteBuffer subBuf = b2.slice();// 生成子缓冲区 System.out.println(b2); //[pos=2 lim=6 cap=15]
System.out.println(subBuf); //[pos=0 lim=4 cap=4] for (int i = 0; i < subBuf.capacity(); i++) {
byte bb2 = subBuf.get(i);
bb2 *= 10; //在子缓冲区中,每个元素都剩以10
subBuf.put(i, bb2);
} b2.position(0);
b2.limit(b2.capacity()); //重置父缓冲区, 并查看父缓冲区的数据
System.out.println(b2);
while(b2.hasRemaining())
System.out.print(b2.get() + " ");
System.out.println();
System.out.println("--------------------------------------"); /**
* 6.只读缓冲区
* asReadOnlyBuffer() //得到一个与当前缓冲区一致,并且共享内存数据的只读缓冲区。
* 可保证核心数据安全,不被随意篡改。原始缓冲区的数据修改,只读缓冲区也是可见的。
*
*/
ByteBuffer b3 = ByteBuffer.allocate(15);
for (int i = 0; i < 10; i++) {
b3.put((byte) i);
} ByteBuffer readOnly = b3.asReadOnlyBuffer(); //创建只读缓冲区
System.out.println(readOnly);
readOnly.flip(); while(readOnly.hasRemaining())
System.out.print(readOnly.get()+ " ");
System.out.println();
b3.put(2,(byte) 20);//修改原始缓冲区数据
//readOnly.put(2, (byte)20); //修改只读缓冲区 会抛出异常 java.nio.ReadOnlyBufferException readOnly.flip();
while(readOnly.hasRemaining())
System.out.print(readOnly.get()+ " "); //新改动在只读缓冲区可见
System.out.println(); /**
* 7.文件映射到内存
* FileChannel.map(); //它比常规的基于流的I/O快很多
*/
RandomAccessFile raf;
try {
raf = new RandomAccessFile("a.txt", "rw");
FileChannel fc = raf.getChannel();
//将文件映射到内存
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, raf.length());
/*while(mbb.hasRemaining())
System.out.println(mbb.get());
*/
mbb.put(0,(byte) 98); //修改文件
raf.close();
} catch (FileNotFoundException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace();
} System.out.println("--------------------------------------------------"); /**
* 8.处理结构化数据,散射(Scattering)和聚集(Gathering)
*
* 散射(Scattering): 值将数据读入一组Buffer中,而不仅仅是一个。
* 聚集(Gathering): 聚集与之相反,将数据写入一组Buffer中。
*
* 在散射读取中,通道依次填充每个缓冲区,填满一个缓冲区后,就开始填充下一个。缓冲区数组就是一个大缓冲区
*/ String Path = "D://a.txt"; try {
//通过聚集写操作创建该文件
ByteBuffer bookBuf = ByteBuffer.wrap("Java性能优化技巧".getBytes("utf-8"));
ByteBuffer autBuf = ByteBuffer.wrap("葛一鸣".getBytes("utf-8")); int booklen = bookBuf.limit();//记录长度
int authlen = autBuf.limit(); ByteBuffer[] bufs = new ByteBuffer[]{bookBuf,autBuf};
File file = new File(Path);
if(!file.exists())
file.createNewFile();//不存在则创建文件 FileOutputStream fos = new FileOutputStream(file);
FileChannel fc = fos.getChannel();
fc.write(bufs);//聚集写文件
System.out.println("写入数据成功");
fos.close(); //使用散射读取文件
ByteBuffer b4 = ByteBuffer.allocate(booklen);//根据实际信息构造Buffer
ByteBuffer b5 = ByteBuffer.allocate(authlen); ByteBuffer[] bufss = new ByteBuffer[]{b4, b5}; //Buffer数组
File f = new File(Path);
FileInputStream fis = new FileInputStream(f);
FileChannel fcl = fis.getChannel(); fcl.read(bufss);//读入数据
String bookName = new String(bufss[0].array(), "utf-8");//取得数据
String authName = new String(bufss[1].array(), "utf-8");//取得数据
System.out.println(bookName + authName); } catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }

Java NIO Buffer说明的更多相关文章

  1. Java NIO Buffer(netty源码死磕1.2)

    [基础篇]netty源码死磕1.2:  NIO Buffer 1. Java NIO Buffer Buffer是一个抽象类,位于java.nio包中,主要用作缓冲区.Buffer缓冲区本质上是一块可 ...

  2. (二:NIO系列) Java NIO Buffer

    出处:Java NIO Buffer Buffer是一个抽象类,位于java.nio包中,主要用作缓冲区.Buffer缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...

  3. java.nio.Buffer 中的 flip()方法

    在Java NIO编程中,对缓冲区操作常常需要使用  java.nio.Buffer中的 flip()方法. Buffer 中的 flip() 方法涉及到 Buffer 中的capacity.posi ...

  4. [翻译] java NIO Buffer

    原文地址:http://tutorials.jenkov.com/java-nio/buffers.html JAVA NIO 是在和channel交互的时候使用的.正如你所知道的,数据是从chann ...

  5. Java NIO Buffer缓冲区

    原文链接:http://tutorials.jenkov.com/java-nio/buffers.html Java NIO Buffers用于和NIO Channel交互.正如你已经知道的,我们从 ...

  6. java NIO Buffer 详解(1)

    1.java.io  最为核心的概念是流(stream),面向流的编程,要么输入流要么输出流,二者不可兼具: 2.java.nio 中拥有3个核心概念: Selector Channel, Buffe ...

  7. Java NIO —— Buffer(缓冲区)

    Buffer是一个抽象类,位于java.nio包中,主要用作缓冲区.注意:Buffer是非线程安全类. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO Buffer ...

  8. java.nio.Buffer源码阅读

    Java 自从 JDK1.4 起,对各种 I/O 操作使用了 Buffer 和 Channel 技术.这种更接近于操作系统的的底层操作使得 I/O 操作速度得到大幅度提升,下面引用一段<Java ...

  9. Java NIO ———— Buffer 缓冲区详解 入门

    引言缓冲区是一个用于特定基本类型的容器.由java.nio 包定义,所有缓冲区都是 Buffer 抽象类的子类. Java NIO 中的 Buffer ,主要用于与NIO 通道进行交互.数据从通道存入 ...

随机推荐

  1. url取值乱码问题,url加中文导致页面不能加载问题 js unicode转码,以及解码

    很多时候写H5或其他适配时,打不开url.很多原因是因为浏览器不支持中文url,从url拿 出来的中文值也会乱码,这时候就必须把中文转化成Unicode值,去进行页面传值 中文转Unicode fun ...

  2. c#中通过事件实现按下回车跳转控件

    //接受用户输入参数后回车事件 private void tb_KeyPress(object sender, KeyPressEventArgs e) { ) { SendKeys.Send(&qu ...

  3. 解决windows64位系统上安装mysql-python报错

    解决windows64位系统上安装mysql-python报错 2018年03月12日 13:08:24 一个CD包 阅读数:1231    版权声明:本文为博主原创文章,未经博主允许不得转载. ht ...

  4. 使用Scrapy爬取图书网站信息

    重难点:使用scrapy获取的数值是unicode类型,保存到json文件时需要特别注意处理一下,具体请参考链接:https://www.cnblogs.com/sanduzxcvbnm/p/1030 ...

  5. 平衡树前置——BST

    上一节:平衡树——序 BST(Binary Search Tree)二叉排序树,其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ①若它的左子树非空,则左子树上所有结点的值均小于根结点的值 ...

  6. hdu2008 数值统计【C++】

    数值统计 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  7. hadoop balancer

    一.balancer是当hdfs集群中一些datanodes的存储要写满了或者有空白的新节点加入集群时,用于均衡hdfs集群磁盘使用量的一个工具.这个工具作为一个应用部署在集群中,可以由集群管理员在一 ...

  8. Git学习总结(3)——代码托管平台简介

    可以说GitHub的出现完全颠覆了以往大家对代码托管网站的认识.GitHub不但是一个代码托管网站,更是一个程序员的SNS社区.GitHub真正迷人的是它的创新能力与Geek精神,这些都是无法模仿的. ...

  9. 算是学完了《Servlet&JSP学习笔记》,立此存照

    我感觉从构架上来说,算是入门了, 终于可以正式进入SPRING的学习啦...爽 代码就不弄了,真的太多了...花了差不多两周呢..

  10. 贪心算法 Heidi and Library (easy)

    A. Heidi and Library (easy) time limit per test 2 seconds memory limit per test 256 megabytes input ...