NIO是对I/O处理的进一步抽象,包含了I/O的基础概念。我是基于网上博友的博客和Ron Hitchens写的《JAVA NIO》来学习的。

NIO的三大核心内容:缓冲区,通道,选择器。

一,buffer缓冲区

1,家谱

除了以上的基础类型对应的buffer之外,还有一种MappedByteBuffer,是ByteBuffer的子类, 专门用于内存映射文件的一种特例。

2,buffer 缓冲区基础

概念上,缓冲区是包在一个对象内的基本数据元素数组。

2.1,属性

容量( capacity)

缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能
被改变。

上界(limit)

缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。

位置(position)

下一个要被读或写的元素的索引。位置会自动由相应的 get( )put( )函数更新。

标记(mark)

一个备忘位置。调用 mark( )来设定 mark = postion。调用 reset( )设定 position =
mark。标记在设定前是未定义的(undefined)。

这四个属性之间总是遵循以下关系:
0 <= mark <= position <= limit <= capacity

2.2,buffer 缓冲区 API

package java.nio;
public abstract class Buffer {
public final int capacity( )
public final int position( )
public final Buffer position (int newPositio
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( );
}

注意:clear()函数一般返回void。isReadOnly()函数用来标记该缓冲区内容是否可改变,因为所有的缓冲区都是可读的,但不一定都是可写的。

2.3,buffer 缓冲区的存取

public abstract class ByteBuffer
extends Buffer implements Comparable
{
// This is a partial API listing
public abstract byte get( );
public abstract byte get (int index);
public abstract ByteBuffer put (byte b);
public abstract ByteBuffer put (int index, byte b);
}

在上文所列出的的 Buffer API 并没有包括 get()或 put()函数。每一个 Buffer 类都有这
两个函数,但它们所采用的参数类型,以及它们返回的数据类型,对每个子类来说都是唯一
的,所以它们不能在顶层 Buffer 类中被抽象地声明。它们的定义必须被特定类型的子类所遵
从。

2.4,翻转

我们已经写满了缓冲区,现在我们必须准备将其清空。我们想把这个缓冲区传递给一个通
道,以使内容能被全部写出。flip()函数将一个能够继续添加数据元素的填充状态的缓冲区翻转成一个准备读出元素
的释放状态。

2.5,批量移动

如果一次只能读取一个字节,那这样的效率太低了,所以buffer有提供批量移动的函数

public abstract class CharBuffer
extends Buffer implements CharSequence, Comparable
{
// This is a partial API listing
public CharBuffer get (char [] dst)
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)
}
有两种形式的 get( )可供从缓冲区到数组进行的数据复制使用。第一种形式只将一个数组
作为参数,将一个缓冲区释放到给定的数组。第二种形式使用 offset 和 length 参数来指
定目标数组的子区间。

3,创建缓冲区

以下API以CharBuffer为例:

public abstract class CharBuffer
extends Buffer implements CharSequence, Comparable
{
// This is a partial API listing
public static CharBuffer allocate (int capacity)
public static CharBuffer wrap (char [] array)
public static CharBuffer wrap (char [] array, int offset,
int length)
public final boolean hasArray( )
public final char [] array( )
public final int arrayOffset( )
}

其中allocate()函数需要指定缓冲区的大小。

4,复制缓冲区

以CharBuffer为例

public abstract class CharBuffer
extends Buffer implements CharSequence, Comparable
{
// This is a partial API listing
public abstract CharBuffer duplicate( );
public abstract CharBuffer asReadOnlyBuffer( );
public abstract CharBuffer slice( );
}

其中Duplicate()函数创建了一个与原始缓冲区相似的新缓冲区。两个缓冲区共享数据元素,拥有同样的容量,但每个缓冲区拥有各自的位置,上界和标记属性。

5,字节缓冲区 ByteBuffer

作为NIO最为重要的ByteBuffer字节缓冲区,只有字节缓冲区能够与NIO通道共用。字节是操作系统及其 I/O 设备使用的基本数据类型。当在 JVM 和操作系统间传递数据时,将其他的数据类型拆分成构成它们的字节是十分必要的。

5.1,字节大小

各个基础类型的字节大小,每个基本数据类型都是以连续字节序列的形式存储在内存中。

在网络传输过程,还会涉及到一个重要的内容:网络字节序。在java代码的网络传输过程中,默认是大端字节顺序。

如果数字数值的最高字节——big end(大端),位于低位地址,那么系统就是大端字节顺序,如果最低字节最先保存在内存中,那么小端字节顺序。

          

大端字节顺序                                     小端字节顺序

当Internet的设计者为互联各种类型的计算机而设计网际协议( IP)时,他们意识到了在具有不同内部字节顺序的系统间传递数值数据的问题。因此, IP协议规定了使用大端的网络字节顺序概念 4。所有在IP分组报文的协议部分中使用的多字节数值必须先在本地主机字节顺序和通用的网络字节顺序之间进行转换。

NIO基础学习——缓冲区的更多相关文章

  1. JAVA NIO 基础学习

    package com.hrd.netty.demo.jnio; import java.io.BufferedReader; import java.io.IOException; import j ...

  2. Java NIO中的缓冲区Buffer(一)缓冲区基础

    什么是缓冲区(Buffer) 定义 简单地说就是一块存储区域,哈哈哈,可能太简单了,或者可以换种说法,从代码的角度来讲(可以查看JDK中Buffer.ByteBuffer.DoubleBuffer等的 ...

  3. Netty学习笔记(一)——nio基础

    Netty简单认识: 1) Netty 是由JBOSS 提供的一个Java 开源框架. 2) Netty 是一个异步的.基于事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络I0 程序. 3) ...

  4. NIO模型学习笔记

    NIO模型学习笔记 简介 Non-blocking I/O 或New I/O 自JDK1.4开始使用 应用场景:高并发网络服务器支持 概念理解 模型:对事物共性的抽象 编程模型:对编程共性的抽象 BI ...

  5. Java NIO 基础知识

    前言 前言部分是科普,读者可自行选择是否阅读这部分内容. 为什么我们需要关心 NIO?我想很多业务猿都会有这个疑问. 我在工作的前两年对这个问题也很不解,因为那个时候我认为自己已经非常熟悉 IO 操作 ...

  6. 毕业设计预习:SM3密码杂凑算法基础学习

    SM3密码杂凑算法基础学习 术语与定义 1 比特串bit string 由0和1组成的二进制数字序列. 2 大端big-endian 数据在内存中的一种表示格式,规定左边为高有效位,右边为低有效位.数 ...

  7. opengl基础学习专题 (一 )编程环境搭建

    题外话: 第一次在博客园上同大家分享博文.水的的地方,错别字的地方.环境交流.批评.知道了马上改. 以前在百度空间中写技术分享博文,后来百度啥也没说就把整个空间封了.当时感觉 还是有点寒心.只想黑一下 ...

  8. Oracle基础学习笔记

    Oracle基础学习笔记 最近找到一份实习工作,有点头疼的是,有阶段性考核,这...,实际想想看,大学期间只学过数据库原理,并没有针对某一数据库管理系统而系统的学习,这正好是一个机会,于是乎用了三天时 ...

  9. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

随机推荐

  1. bash、dash(/bin/bash和/bin/sh)的区别

    Linux中的shell有多种类型,其中最常用的几种是Bourne   shell(sh).C   shell(csh)和Korn   shell(ksh).三种shell各有优缺点. Bourne ...

  2. 对数组名取地址&a和 数组首地址a

    #include <iostream> using namespace std; ] = {,,,,}; int main() { cout<<a<<" ...

  3. 自定义封装 banner 组件

    1. 效果图预览 2.基本功能 一个简单方便的轮播图组件,基于viewpager 基础上进行的封装.可设置 项目中图片,网络图片, View:支持循环自动播放,手势滑动切换,item点击事件,可设置 ...

  4. 【sqli-labs】 less64 GET -Challenge -Blind -130 queries allowed -Variation3 (GET型 挑战 盲注 只允许130次查询 变化3)

    双括号整型 http://192.168.136.128/sqli-labs-master/Less-64/?id=1)) or ((1

  5. Jenkins系列之Jenkins的工具配置和插件(二)

    上一篇我们介绍了Jenkins的安装,这一篇我们介绍如何配置Jenkins的工具和如何下载插件. 首先我们先来看如何配置工具,这里的工具是指JDK.Ant.Maven.Git等. 一.如图,点击系统管 ...

  6. 梦想CAD控件 2019.01.20更新

    下载地址:http://www.mxdraw.com/ndetail_10120.html1. 修改CAD不等比例块保存问题2. 修改CAD捕捉时,Z值对捕捉不准的影响3. 修改图片对象选择后,自动跑 ...

  7. Apache 和 Nginx 下的 URL 重写

    URL 重写和重定向 URL 重写是将页面映射到本站另一页面, 而重定向则是将页面映射到另一主机(域名). 其中临时重定向(R=302)和永久重定向(R=301)都是亲搜索引擎的, 是 SEO 的重要 ...

  8. BeanFactory的生命周期

    Bean自身的方法:调用Bean构造函数实例化Bean.调用setter设置Bean的属性值及通过<beam=n>的init-method和destory-method所制定的方法. Be ...

  9. git 的 基础操作及使用

    /* git svn版本控制器 */ /*git把文件对应的储存空间分为三个区: 1.工作区 2.缓存区 3.历史区 直接操作文件,不做add时,咱们是在工作区做的修改 右键 git bash her ...

  10. linux tload-显示系统负载状况

    推荐:更多linux 性能监测与优化 关注:linux命令大全 tload命令以图形化的方式输出当前系统的平均负载到指定的终端.假设不给予终端机编号,则会在执行tload指令的终端机显示负载情形. 语 ...