本文来自于我的个人博客:java nio 缓冲区(一)

我们以Buffer类開始对java.nio包的浏览历程。这些类是java.nio的构造基础。

这个系列中,我们将尾随《java NIO》书籍一起深入研究缓冲区,了解各种不同的类型。并学会如何使用。

一个Buffer对象是固定数量的数据容器。其作用是一个存储器。或者分段运输区。在这里数据可被存储并在之后用于检索。

Buffer类的家谱:

一,缓冲区基础

1.缓冲区的属性:

容量(capacity):缓冲区可以容纳的数据元素的最大数量。这一容量是在缓冲区被创建时设置的,而且永远不能被改变

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

位置(position): 下一个要被读或写的元素的索引,位置会自己主动由对应的get()和put()函数更新。

标记(mark): 一个备忘位置,调用mark()来设定mark=position.调用reset()设定position=mark。

标记在设定前是没有定义的(undefied)。

这四个属性的关系例如以下:

0 <= mark <= position <= limit <= capacity

接下来,我们看看这些属性在实际应用中的一些样例:

创建一个新的ByteBuffer,则缓冲区的各个属性状态例如以下图所看到的:

位置被设置为0,并且容量和上界被设为10,刚好经过缓冲区可以容纳的最后一个字节。

标记最初没有定义,容量是固定的,但另外三个属性可以在使用缓冲区时改变。

2.缓冲区API

让我们来看看假设使用一个缓冲区,下面是Buffer类的方法:

package java.nio;
public abstract class Buffer {
    public final int capacity();
    public final int position();
    public final Buffer position(int newPosition);
    public final int limit();
    public final Buffer limit(int newLimit);
    public final Buffer mark();
    public final Buffer reset();
    public final Buffer flip();
    public final Buffer rewind();
    public final int remaining();
    public final boolean hasRemaining();
    public abstract boolean isReadOnly();
}

关于这个API。有一点要注意,像clear()这类方法,通常应当返回void,而不是Buffer引用。这些函数将引用返回到它们在(this)上被引用的对象。这是一个同意级联调用的类设计方法。

级联调用同意这样的类型的代码:

buffer.mark();

buffer.position(5);

buffer.reset();

被简写为:buffer.mark().position(5).reset();

3.存取

我们将代表"Hello"字符串的ASCII码加载一个名为buffer的ByteBuffer对象中,缓冲区的结果状态例如以下图所看到的:

buffer.put((byte)'H').put((byte)'e').put((byte)'1').put((byte)'1').put((byte)'o');

既然已经在buffer中存放了一些数据。如果我们想在不丢失位置的情况下进行一些更改该怎么办呢?put()的绝对方案能够达到这种目的。如果我们想将缓冲区中的内容从"Hello"的ASCII码更改为"Mellow"。我们能够这样实现:

buffer.put(0,(byte)'M').put((byte)'w');改动后的buffer例如以下图所看到的:

4.翻转

在我们写满了缓冲区之后,如今我们必须准备将其清空。

我们想把这个缓冲区传递给一个通道,以使内容能被所有写出,但假设通道如今在缓冲区上运行get(),那么它将从我们刚刚插入的游泳数据之外取出没有定义的数据,假设我们将位置设置为0,通道就会从正确位置開始获取。可是它使如何知道何时叨叨我们所插入数据末端的呢?这就是上界属性被引入的目的。buffer.limit(buffer.position()).position(0),可是这样的从填充到释放转台的缓冲区翻转是预先设计好的。设计者为我们提供了更便利的方法buffer.flip(),flip方法将一个可以继续加入数据元素的填充状态的缓冲区饭庄成一个准备读出元素的释放状态。在翻转之后,缓冲区的状态例如以下图所看到的:

rewind()方法与flip()方法相似,可是它会改变limit的值,仅仅是将position的值设置为0,这种方法能够用于回退已经度过的数据以便又一次读取已经读过的数据。

方法hasRemaining会告诉你,是否已经达到缓冲区的上界,即limit-position=0,下面是一种将数据元素从缓冲区释放到一个数组的方法:

for(int i = 0; buffer.hasRemaining();i++{

byteArray[i] = buffer.get();

}

另一种选择是使用remainig()方法。这种方法告诉你还剩余多少元素数目可被存入,能够依据下面方法释放缓冲:

int count = buffre.remaining();

for(int i = 0; i < count;i++) {

byteArray[i] = buffer.get();

}

5.以下是一个样例来填充以及释放缓冲区:

import java.nio.CharBuffer;
public class BufferFillDrain{
    private static int index = 0;
    private static String[] strings = {
        "hello word",
        "java is very beautiful",
        "python is very brief"
    };
    public static void main(String[] args) throws Exception{
        CharBuffer buffer = CharBuffer.allocate(100);
        while(fillBuffer(buffer)) {
            buffer.flip();
            drainBuffer(buffer);
            buffer.clear();
        }
    }
    
    private static void drainBuffer(CharBuffer buffer) {
        while(buffer.hasRemaining()) {
            System.out.println(buffer.get());
        }
    }
    
    private static boolean fillBuffer(CharBuffer buffer) {
        if(index >= strings.length) {
            String string = strings[length];
            for(int i = 0; i < strings.length(); i++) {
                buffer.put(string.charAt(i));
            }
        }
        return true;
    }
}

6.压缩

有时。我们可能仅仅想从缓冲区中释放一部分数据。而不是所有。然后又一次填充,为了实现这一点,未读的数据元素须要下移以使第一个元素索引为0。而API对此提供了一个compact()方法,在释放缓冲区曾经。可能有个缓冲区例如以下所看到的:

调用buffer.compact()方法之后。缓冲区的状态例如以下图所看到的:

能够看到,已经将释放的字节剔除。然后position的位置将会变为limit - originPosition。limit则被设置为limit=capacity。然后又又一次从position位置填充数据。

7.缓冲区的比較

两个被觉得是同样缓冲区的条件是从position位置開始到limit位置结束。这段字节之内的数据同样,则说明两个缓冲区同样,比較方法为buffer.compareTo(buffer),例如以下图所看到的两个缓冲区同样:

java nio 缓冲区(一)的更多相关文章

  1. Java NIO -- 缓冲区(Buffer)的数据存取

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

  2. JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法

    参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...

  3. Java NIO 缓冲区

    Java NIO 在JDK1.4的时候引入,主要解决传统IO的一些性能问题.NIO 主要内容包含 Buffer .Channel.Selector等内容,本文主要讲解Buffer相关的内容. Buff ...

  4. Java NIO 缓冲区 Buffer

    缓冲区 Buffer 是 Java NIO 中一个核心概念,它是一个线性结构,容量有限,存放原始类型数据(boolean 除外)的容器. 1. Buffer 中可以存放的数据类型 java.nio.B ...

  5. Java NIO 缓冲区学习笔记

    Buffer其实就是是一个容器对象,它包含一些要写入或者刚读出的数据.在NIO中加入Buffer对象,体现了新库与原I/O的一个重要区别.在面向流的I/O中,您将数据直接写入或者将数据直接读到Stre ...

  6. java nio 缓冲区读写数据(图形详解)

    Position 您可以回想一下,缓冲区实际上就是美化了的数组.在从通道读取时,您将所读取的数据放到底层的数组中. position 变量跟踪已经写了多少数据.更准确地说,它指定了下一个字节将放到数组 ...

  7. JAVA NIO学习笔记二 频道和缓冲区

    Java NIO 频道 Java NIO渠道类似于流,他们之间具有一些区别的: 您可以读取和写入频道.流通常是单向(读或写). 通道可以异步读取和写入数据. 通道常常是读取或写入缓冲区. 如上所述,您 ...

  8. Java-杂项-java.nio:java.nio

    ylbtech-Java-杂项-java.nio:java.nio java.nio全称java non-blocking IO,是指jdk1.4 及以上版本里提供的新api(New IO) ,为所有 ...

  9. JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁

    IO  是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...

随机推荐

  1. ViewPager (下)-- 利用 Fragment 实现美丽的 页面切换

    之前用的ViewPager适用于简单的广告切换,但实现页面间的切换最好是用官方推荐的Fragment来处理. 本人力争做到最简单.最有用,是想以后用到的时候能够方便的拿过来复制就能够了. 效果图: w ...

  2. 纯C++实现的HTTP请求封装(POST/GET)

    纯C++实现的HTTP请求(POST/GET),支持windows和linux, 进行简单的封装, 方便调用.实现如下: #include "HttpConnect.h" #ifd ...

  3. 27. Spring Boot 部署与服务配置

    转自“https://www.cnblogs.com/zhchoutai/p/7127598.html” Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函 ...

  4. LOJ 6229 LCM / GCD (杜教筛+Moebius)

    链接: https://loj.ac/problem/6229 题意: \[F(n)=\sum_{i=1}^n\sum_{j=1}^i\frac{\mathrm{lcm}(i,j)}{\mathrm{ ...

  5. 24.C语言最全排序方法小结(不断更新)

    希尔排序: 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再 ...

  6. 学习笔记:Vue——处理边界情况

    访问元素&组件 01.访问根实例 $root // Vue 根实例 new Vue({ data: { foo: 1 }, computed: { bar: function () { /* ...

  7. “焦点图/幻灯片”“Tab标签切换”“图片滚动”“无缝滚动”仅需一个SuperSlidev2.1

    官网:http://www.superslide2.com/index.html 1. 标签切换 / 书签切换 / 默认效果 2. 焦点图 / 幻灯片 3. 图片滚动-左 4. 图片滚动-上 5. 图 ...

  8. 从软件project的角度写机器学习3——主要监督学习算法的project性分析

    主要机器学习算法的project适用性分析 前段时间AlphaGo跟李世石的大战及相关的深度学习的新闻刷了一遍又一遍的朋友圈.只是这件事情,也仅仅是在机器学习的深度上进一步拓展,而机器学习的广度(也即 ...

  9. Day2:列表、元组

    一.列表 1.定义与访问元素(按索引) #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan list_a = [&quo ...

  10. 使用Samba在Linux服务器上搭建共享文件服务

    最近我们的小团队需要在服务器上共分出一个共享文件夹用于大家存放公共的资源文档, 大家想啊,这肯定很简单呀,在Windows下面只要创建相关的windows account,共享某个文件夹,把读/写权限 ...