Java NIO Buffer

3 篇文章 0 订阅

Java NIO中的Buffer用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。

NIO中的关键Buffer实现有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer,分别对应基本数据类型: byte, char, double, float, int, long, short。当然NIO中还有MappedByteBuffer, HeapByteBuffer, DirectByteBuffer等这里先不进行陈述。

首先我们先创建一个Buffer

 //create buffer with capacity of 11bytes
 ByteBuffer buf = ByteBuffer.allocate(11);

可以把Buffer简单地理解为一组基本数据类型的元素列表,它通过几个变量来保存这个数据的当前位置状态:

索引说明
capacity缓冲区数组的总长度
position下一个要操作的数据元素的位置
limit所有对Buffer读写操作都会以limit变量的值作为上限。


我们通过ByteBuffer.allocate(11)方法创建了一个11个byte的数组的缓冲区,初始状态如上图,position的位置为0,capacity和limit默认都是数组长度。当我们写入5个字节时,变化如下图:
这里写图片描述
这时我们需要将缓冲区中的5个字节数据写入Channel的通信信道,所以我们调用ByteBuffer.flip()方法,变化如下图所示(position设回0,并将limit设成之前的position的值):
这里写图片描述
这里再次解释一下limit:
在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。
当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。

clear方法

    public final Buffer clear() {
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }

clear将缓冲区清空,一般是在重新写缓冲区时调用。

flip方法

    public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

首先将limit设置为当前位置,然后将position设置为 0。如果已定义了标记。 常与compact方法一起使用。通常情况下,在准备从缓冲区中读取数据时调用flip方法。

compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。

hasRemaining

    public final boolean hasRemaining() {
        return position < limit;
    }
package com.hutonm.nio;

import org.junit.Before;
import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.RandomAccess;

public class Niotest {

    @Test
    public void method1(){
        RandomAccessFile aFile = null;

        try {
            aFile = new RandomAccessFile("src/nio.text","rw");
            FileChannel fileChannel = aFile.getChannel();

            //create buffer with capacity of 1024 bytes
            ByteBuffer buf = ByteBuffer.allocate(1024);
            //read into buffer
            int byteRead = fileChannel.read(buf);

            // print byteRead
            //System.out.println(byteRead);


            while (byteRead != -1){

                //make buffer read for read
                buf.flip();

                while (buf.hasRemaining()){
                    System.out.print((char)buf.get());
                }

                //清除已读数据
                buf.compact();

                byteRead = fileChannel.read(buf);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

参考:
http://www.importnew.com/19816.html
http://ifeve.com/buffers/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值