`
orange5458
  • 浏览: 347631 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

nio(一)Buffer

 
阅读更多

1.简介

Buffer是一种用于特定的基本类型数据的容器,是特定的基本类型元素的线性、有限序列。

1.1 Buffer有四个相当重要的属性:

1)capacity:容量,Buffer所能够容纳的基本类型数据的数量。

2)mark:标记,Buffer中的一个位置

3)position:位置,下一个读写操作的元素在Buffer中的位置。

4)limit:限制,禁止读写操作的第一个元素的索引

1.2 四个属性之间的关系

0 <= 标记 <= 位置 <= 限制 <= 容量

1.3 影响四个属性的相关操作

1)public final Buffer mark()

在Buffer的位置设置标记

2)public final Buffer reset()

将Buffer的位置设置为之前的标记值,如果标志不存在则抛出InvalidMarkException

3)public final Buffer position(int newPosition)

设置Buffer的位置,如果标记已定义并且大于新的位置,则要丢弃该标记

newPosition范围[0,limit],否则抛出IllegalArgumentException

4)public final Buffer limit(int newLimit)

设置此缓冲区的限制。

如果位置大于新的限制,则它被设置为此新限制。

如果标记已定义并且大于新限制,则要丢弃该标记。

newPosition范围[0,capacity],否则抛出IllegalArgumentException

5)public final Buffer flip()

反转此缓冲区。

首先对当前位置设置限制,然后将该位置设置为零。

如果已定义了标记,则丢弃该标记。

效果等同于Buffer.limit(Buffer.position()); + Buffer.position(0);

6)public final Buffer rewind()

重绕此缓冲区。将位置设置为零并丢弃标记。

效果等同于Buffer.position(0);

7)public final Buffer clear()

清除此缓冲区。将位置设置为零,限制设置为该容量,并且丢弃标记。

注:此方法不能实际擦除缓冲区中的数据

效果等同于Buffer.limit(Buffer.capacity()); + Buffer.position(0);

8)put/get等当前位置存取方法均会使位置向前移动N个单位,存取操作的位置不能大于限制

9)put/get等绝对位置存取方法均不会改变Buffer的位置和限制

2.个人总结

1)关于写

Buffer通过position来控制读写操作的元素位置,每次写操作后都会将position向后移动写入数据的长度,因此一个连续的写操作的作用范围为从第1个写操作的position1到第N个写操作的positionN,即[position1, positionN+length(dataN))且0<=position1<positionN+length(dataN)<=limit。

2)关于读

由写的过程可知写的内容位于[position1, positionN+length(dataN))之间,所以读取写内容的时候也必须读取该范围的内容。

3)程序使用

程序使用Buffer时通过每次记录写操作的position1和positionN+length(dataN)不可行,因为可能对象A对Buffer进行写操作,并且只返回Buffer对象给需要读Buffer的对象B。

所以要利用Buffer的属性进行读写操作,使得

每次写操作开始前使postion=0,limit=capacity,这样写操作范围为[0, limit) = [0, capacity),即调用方法clear()

在写操作结束后读取内容前使limit=position,postion=0,这样读操作范围为[0, limit) = [position1, positionN+length(dataN)),即调用方法flip()

 第一次读取内容后要重复读取内容前只需使postion=0,这样读操作范围为[0, limit) = [position1, positionN+length(dataN)),即调用方法rewind()

3.实例

package com.siyuan.test.jdk.nio;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.InvalidMarkException;

public class BufferTest {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int BSIZE = 1024;
		ByteBuffer bBuffer = ByteBuffer.allocate(BSIZE);
		System.out.println("初始化...");
		System.out.println(getBufferStatus(bBuffer));
		bBuffer.putChar('a');
		System.out.println("在位置写入字符a后");
		System.out.println(getBufferStatus(bBuffer));
		bBuffer.mark();
		bBuffer.putChar('b');
		System.out.println("在位置设置标记,写入字符b后");
		System.out.println(getBufferStatus(bBuffer));
		int lastPosition = bBuffer.position(); //记录缓冲区有效字符的终结位置
		bBuffer.reset(); //效果等同于bBuffer.position(2);
		System.out.println("将位置设置为标志后");
		System.out.println(getBufferStatus(bBuffer));
		
		//读数据
		//设置位置,如果标记已定义并且大于新的位置,则要丢弃该标记
		bBuffer.position(lastPosition);
		/*
		 *将限制设置为位置,然后将位置设置为0,如果已定义了标记,则丢弃该标记
		 *常用于向buffer中写入数据后和从buffer中读取数据前 
		 *效果等同于 
		 *bBuffer.limit(bBuffer.position());
		 *bBuffer.position(0);
		 */
		bBuffer.flip(); 
		System.out.println("还原位置,flip后");
		System.out.println(getBufferStatus(bBuffer));
		while (bBuffer.hasRemaining()) {
			System.out.print(bBuffer.getChar());
		}
		System.out.println("读取完位置和限制之间的数据后");
		System.out.println(getBufferStatus(bBuffer));
		
		//重新读取
		/*
		 * 重绕此缓冲区。将位置设置为零并丢弃标记。
		 * 效果等同于
		 * Buffer.position(0);
		 */
		bBuffer.rewind();
		System.out.println("rewind后");
		System.out.println(getBufferStatus(bBuffer));
		while (bBuffer.hasRemaining()) {
			System.out.print(bBuffer.getChar());
		}
		System.out.println("读取完位置和限制之间的数据后");
		System.out.println(getBufferStatus(bBuffer));
		
		//重新写入数据
		/*
		 * 清除此缓冲区。将位置设置为零,限制设置为该容量,并且丢弃标记。
		 * 注:此方法不能实际擦除缓冲区中的数据
		 * 通过position和limit来确定有效数据的存储区域
		 * 效果等同于 
		 * bBuffer.limit(buffer.capacity());
		 * bBuffer.position(0);
		 */
		bBuffer.clear();
		System.out.println("clear后");
		System.out.println(getBufferStatus(bBuffer));
		bBuffer.putChar('b');
		bBuffer.putChar('b');
		bBuffer.putChar('c');
		bBuffer.putChar('c');
		System.out.println("在位置写入bbcc后");
		System.out.println(getBufferStatus(bBuffer));
		
		/*
		 * 绝对位置读取,不影响Buffer的属性
		 */
		System.out.println(bBuffer.getChar(4));
		System.out.println("在绝对位置4读取字符后");
		System.out.println(getBufferStatus(bBuffer));
		
		/*
		 * 绝对位置写入,不影响Buffer的属性,
		 * 且写入方式为覆盖,而不是插入
		 */
		bBuffer.putChar(4, 'd');
		System.out.println("在绝对位置4写入字符d后");
		System.out.println(getBufferStatus(bBuffer));
		
		System.out.println("重新读取Buffer的内容");
		bBuffer.flip();
		while (bBuffer.hasRemaining()) {
			System.out.print(bBuffer.getChar());
		}
	}
	
	public static final String getBufferStatus(Buffer buffer) {
		StringBuilder str = new StringBuilder();
		str.append("容量:").append(buffer.capacity())
			.append(",位置:").append(buffer.position())
			.append(",限制:").append(buffer.limit());
		boolean markExist = false;
		try {
			int position = buffer.position();
			buffer.reset();
			markExist = true;
			buffer.position(position);
		} catch(InvalidMarkException e) {
		}
		str.append(",存在标志: ").append(markExist);
		return str.toString();
	}
	
}

    运行结果:

初始化...
容量:1024,位置:0,限制:1024,存在标志: false
在位置写入字符a后
容量:1024,位置:2,限制:1024,存在标志: false
在位置设置标记,写入字符b后
容量:1024,位置:4,限制:1024,存在标志: true
将位置设置为标志后
容量:1024,位置:2,限制:1024,存在标志: true
还原位置,flip后
容量:1024,位置:0,限制:4,存在标志: false
ab读取完位置和限制之间的数据后
容量:1024,位置:4,限制:4,存在标志: false
rewind后
容量:1024,位置:0,限制:4,存在标志: false
ab读取完位置和限制之间的数据后
容量:1024,位置:4,限制:4,存在标志: false
clear后
容量:1024,位置:0,限制:1024,存在标志: false
在位置写入bbcc后
容量:1024,位置:8,限制:1024,存在标志: false
c
在绝对位置4读取字符后
容量:1024,位置:8,限制:1024,存在标志: false
在绝对位置4写入字符d后
容量:1024,位置:8,限制:1024,存在标志: false
重新读取Buffer的内容
bbdc

 4.参考资料

JDK文档

分享到:
评论

相关推荐

    动态演示nio中的buffer相关操作.zip

    可以动态演示nio中buffer的相关操作,直观看到各种重要数据的变化,方便大家更好的理解nio的buffer模型

    Java NIO实战开发多人聊天室

    05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-SocketChannel.mp4 10-Java NIO-Channel-...

    NIO详细介绍channle,buffer,Selector

    主要介绍一些关于NIO 的基础知识,有浅到深

    java网络编程NIO视频教程

    05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 07-Java NIO-Channel-Socket通道-概述.mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-...

    尚硅谷Java视频_NIO 视频教程

    尚硅谷_NIO_缓冲区(Buffer)的数据存取 ·03. 尚硅谷_NIO_直接缓冲区与非直接缓冲区 ·04. 尚硅谷_NIO_通道(Channel)的原理与获取 ·05. 尚硅谷_NIO_通道的数据传输与内存映射文件 ·06. 尚硅谷_NIO_分散读取与聚集...

    详细了解JAVA NIO之Buffer(缓冲区)

    主要介绍了JAVA NIO之Buffer(缓冲区)的相关资料,文中讲解非常细致,帮助大家更好的学习JAVA NIO,感兴趣的朋友可以了解下

    Java NIO Buffer过程详解

    主要介绍了Java NIO Buffer过程详解,缓冲区在java nio中负责数据的存储。缓冲区就是数组。用于存储不同数据类型的数据。,需要的朋友可以参考下

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

    Java NIO系列教程

    Java NIO系列教程 Java NIO Channel Buffer Selector SocketChannel

    基于Nio的多人聊天Demo

    NIO即non-blocking IO,顾名思义是一种非阻塞模型。NIO的目的就是实现一个线程处理多个连接。实现多人聊天消息转发,用户发送消息同步到服务中的其他客户端,运用到了nio中buffer、socket、selector。 1、Channel,...

    Java IO, NIO and NIO.2(Apress,2015)

    Next, you'll learn about NIO's buffer, channel, selector, regular expression, charset, and formatter APIs. Finally, you'll discover NIO.2's offerings in terms of an improved file system interface, ...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    Java性能优化之使用NIO提升性能(Buffer和Channel)

    NIO是NewI/O的简称,具有以下特性:为所有的原始类型提供(Buffer)缓存支持;使用java.nio.charset.Charset作为字符集编码解码解决方案;增加通道(channel)对象,作为新的原始I/O抽象;支持锁和内存映射文件的...

    nio:Go #golang中的并发缓冲IO

    ReadWriter} nio的Copy方法同时从io.Reader复制到提供的nio.Buffer,然后从nio.Buffer复制到io.Writer。 这样,阻止写入不会降低io.Reader的速度。 import ( "github....

    Java+NIO+中文版.pdf

    java nio作者倾力所写的简单易懂的NIO学习指南,让你顺利拿下NIO开发,包括了NIO中的Buffer,Channel,Selector的介绍,理论&代码都有,是你学习NIO的不二法宝~

    Java NIO 英文文字版

    The NIO package includes many things that have been missing from previous editions of Java that are critical to writing high-performance, large-scale applications: improvements in the areas of buffer ...

    NIO概述

    2.2 NIO概述 NIO NIO ==&gt; New IO(新IO), Non-Block IO(非阻塞IO) NIO非阻塞IO,运行当前程序在处理IO事务时,不会影响其他程序的运行,可以在不使用多线程的情况下,满足IO操作要求。...java.nio.Buffer Buffe

    nio Buffer internals

    NULL 博文链接:https://wutaoo.iteye.com/blog/419232

Global site tag (gtag.js) - Google Analytics