所谓的输入,输出,就是把数据移除或移入缓冲区。
 

硬件不能直接访问用户控件(JVM)。
基于存储的硬件设备操控的是固定大小的数据块儿,用户请求的是任意大小的或非对齐的数据块儿。
 
虚拟内存:使用虚拟地址取代取代物理地址。
  1. 可以有多个虚拟地址指向同一个物理地址。
  2. 虚拟内存空间可以大于实际的硬件内存。
应用:直接内存使用--使用户空间虚拟地址和内核虚拟地址同时指向同一个物理地址,可以使硬件直接访问用户空间内存。
 

数据库等应用严重依赖文件锁定。

缓冲区:

缓冲区是包在一个对象内的基本数据类型数组。Buffer把关于数据内容和信息包含在一个对象中,并定义了一系列API。
 
信息提供操作属性:0<=mark<=position<=limit<=capicity
  1. 容量(Capicity):创建时设定,无法动态更改。
  2. 上界(Limit):现存元素计数。
  3. 位置(Position):下一个要被读取的元素位置。动态更新。
  4. 标记(Mark):备忘位置,mark()设定mark=position,reset()设定postion=mark。
 
插入“hello”之后:
 

Buffer类方法签名:
返回Buffer自身的一些方法可以直接级联调用。
 
创建只读缓存。例如ByteBuffer:
ByteBuffer bf = ByteBuffer.allocate(1024).asReadOnlyBuffer()
 
Flip():讲一个能够继续添加数据元素的填充状态的缓冲区翻转为一个准备读出元素的释放状态。
bf.flip() = bf.limit(bf.position()).position(0)
 

rewind():
bf.rewind() = bf.position(0)
 
缓冲区不是线程安全。
 
mark():Buffer是从当前位置开始向通道内输出内容的,如下,怎会输出‘ow’,position到6

reset()后,positon至mark位置。
 
两个具有相同元素的Buffer,只要剩余元素数量(从位置到上界)相同,就equals=true。
 
Buffer.get(byte[]):BufferUnderflowException;
当将一个buffer内容读入数组,buffer内容不足以填充数组时,会抛出此异常。因为需要指明可以读入的buffer内容长度。如下:
Buffer.get(byte[], 0, Buffer.remaining());
 
Buffer.put(byte[]):BufferUnderflowException;
当将数组元素写入buffer,buffer没有足够的空间时,会抛出此异常。
 
Buffer.wrap(byte[], int offset, int length):offset,length只是设置了初始化状态,并不是创建只占数组子集的缓冲区,缓冲区可以可以存取数组的全部范围。区别slice函数。
 
allocate(), wrap() 创建的缓冲区都是间接的,使用备份数组,可以获得数组的操作权。
 
Duplicate()复制缓冲区会创建一个新的Buffer对象,但是并不复制数据,原始缓冲区和副本会操作同样的数据元素。
 
Slice() 创建从原始缓冲区当前位置开始的新的缓冲区,容量是原始缓冲区的剩余容量,(limit-position),与原始缓冲区共享一段数据元素子序列。分割出来的子序列继承只读和直接属性。
 

每个基本的数据类型都是以连续的字节序列存储在内存中,多字节被存储在内存中的方式称为字节顺序(endian-ness)。如果数字数值的最高字节--big-end(大端)位于低位地址,那么系统就是大端字节顺序,反之小端字节顺序。
 
IP协议规定了使用大端的网络字节顺序概念。
 
通过ByteOrder.nativeOrder() 输出LITTLE_ENDIAN或者BIG_ENDIAN判断。
 
Java默认的字节序是大端序,系统无关性,ByteBuffer.order() 总是范围ByteOrder.BIG_ENDIAN。
 
只有字节缓冲区有资格参与IO操作,IO操作的目标区域必须是连续的字节序列。JVM中的数据字节数组可能存储不连续,切GC可能会对其进行移动。所以IO不能直接操作。
 
直接缓冲区用于与通道或固有IO例程交互,通过固有代码告知系统直接操作内存区域。
直接缓冲区=》通道
非直接缓冲区=》临时直接缓冲区=》IO=》临时直接缓冲区回收。
 
选择依据执行频率,高频脚本使用直接缓存区。
 
创建直接缓冲区是调用本地操作系统分配的内存,比基于JVM创建的基于堆栈的缓冲区更加耗费,所以也不会被回收管理。
 
先使其工作,再加快其运行。首先注重正确性。过早的优化是所有祸害的根源。
 
ByteBuffer.allocateDirect(),开辟直接内存。
 
视图缓冲区:
 
通过已有的缓冲区对象示例的工厂方法来创建。视图缓冲维护自己的属性、容量、位置、上界和标记,但是和原来的缓冲区共享数据元素。如,ByteBuffer类允许创建视图来将byte型缓冲数组转化为其它的原始类型,ByteBuffer.asLongBuffer()。为基础缓冲区的切分,基于基础缓冲区的位置和上界(position-limit)
 
如下,ByteBuffer.asCharBuffer():
     ByteBuffer中的两个字节映射成CharBuffer中的一个字符,CharBuffer中的字节排序不可以再改变。
 
数据元素视图:
以多字节数据形式存取byte数据组,存取和转化:
从ByteBuffer的当前位置存取字节数据,根据缓冲区当前的有效字节数序,字节会被排列或打乱成原始的数据类型。
例如getInt(),从当前位置开始的四个字节会被包装成一个Int返回。如下:
 
映射缓冲区(MappedByteBufefer):
通过内存映射存取元素的字节缓冲区,直接存取内存,只能通过FileChannel类创建。

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说明

    Buffer 有3个重要的参数:位置(position).容量(capactiy).上限(limit) 位置(position): 写:当前缓冲区的位置,将从position的下一个位置写数据. 读: ...

  9. java.nio.Buffer源码阅读

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

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

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

随机推荐

  1. WCF学习之旅—基于ServiceDebug的异常处理(十七)

    WCF学习之旅—WCF中传统的异常处理(十六) 二.基于ServiceDebug的异常处理 从前面的示例中,可以看到客户端捕获了异常,这是我们处理异常的前提.为了有利于我们进行有效的调试,WCF提供了 ...

  2. 通过easyui tab添加的子页面JS脚本必须放在body才生效

    通过easyui tab添加的子页面JS脚本必须放在body才生效 可通过Chrome查看元素时,head标签是否含有你自己写的JS代码

  3. ASP.NET MVC系列:Area

    1. Area简介 ASP.NET MVC Area机制构建项目,可以将相对独立的功能模块切割划分,降低项目的耦合度. 2. Area设置Routing 新建Admin Area后,自动创建Admin ...

  4. .Net使用RabbitMQ详解

    序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其中,就把他抛开,我们只谈消息Rabbi ...

  5. 在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token

    OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft.Owin.Security.OAuth应运而生(它的实现代码在Katana项目中),帮 ...

  6. 带搜索的ComboBox

    带搜索的ComboBox就是给ComboBox一个依赖属性的ItemSource,然后通过数据源中是否包含要查询的值,重新给ComboBox绑定数据源. public class EditComboB ...

  7. 面向对象的JS(一)

    JavaScript是弱类型,可变性强 /*JavaScript和其他的语言类似,也是面向对象,自然也就是存在类和对象(对象是类的实例化)*/ //1.JS对象 var empty = {}; //没 ...

  8. 关于join时显示no join predicate的那点事

    我们偶尔,非常偶尔的情况下会在一个查询计划中看到这样的警告: 大红叉,好吓人啊! 把鼠标放上去一看显示这样的信息 No join predicate 直译过来就是:没有连接谓词 在真实的生产环境下我们 ...

  9. Django models对象的select_related方法(减少查询次数)

    表结构 先创建一个新的app python manage.py startapp test01 在settings.py注册一下app INSTALLED_APPS = ( 'django.contr ...

  10. Java DNS查询内部实现

    源码分析 在Java中,DNS相关的操作都是通过通过InetAddress提供的API实现的.比如查询域名对应的IP地址: String dottedQuadIpAddress = InetAddre ...