欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java NIO Buffer

程序员文章站 2024-03-06 16:30:14
...

1. 简介

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

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

2. Buffer的capacity,position和limit

对buffer的操作核心就是对position和limit指针位置的操作。
java NIO Buffer
capacity

作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空才能继续写数据往里写数据。

position

当你写数据到Buffer中时,position表示当前的位置。初始的position值为0,当写入/读取一个数据的时候position会+1。position最大可为capacity – 1。
调用flip()切换读模式的时候,position会重置为0.

limit

在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity。
当切换Buffer到读模式时, limit表示你最多能读到多少数据。limit会被设置成之前的position值,换句话说,你能读到之前写入的所有数据。

3. Buffer的类型

Java NIO 有以下Buffer类型

ByteBuffer
MappedByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer

4. Buffer的基本用法

标准流程:
1 . 创建buffer,写入数据到Buffer
2 .调用flip()方法,将limit = position ,position = 0,切换读模式
3 .从Buffer中读取数据
4 .读取完成后调用clear()方法或者compact()方法,是指针复位,以备下次读取。

注意事项:
1 . flip()方法不能连续调用多次,否则指针会混乱
2 . clear()方法并不能真正清除数据,只是将指针复位,待下次写入数据时就可以覆盖原数据。如果需要连续写入,在第一次写入完成后调用mark()标记位置,然后在需要再次写入的时候调用reset()复位。
3 . Channel
read()方法是写入buffer,写入前应该是刚创建的buffer或者调用一次clear;
write()方法是读取buffer。读取前应该调用一次flip();

示例代码:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
//create buffer with capacity of 48 bytes
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf); //read into buffer.
while (bytesRead != -1) {
  //切换读模式
  buf.flip();  //make buffer ready for read
  while(buf.hasRemaining()){
      System.out.print((char) buf.get()); // read 1 byte at a time
  }
}
buf.clear();
aFile.close();

5.Buffer实用工具类

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Calendar;

/**
 * @author: zonglin_wu
 * @Date: 2018/7/25 19:42
 * @Description:
 */
public class ByteBufferUtil {

    public static byte[] readByte(ByteBuffer byteBuffer){
        byte[] b = null;
        //为读者做准备,切换读模式
        byteBuffer.flip();
        b = new byte[byteBuffer.limit()];
        byteBuffer.get(b);
        //清楚标记位
        byteBuffer.clear();
        return b;
    }

    /**
     *  读取byteBuffer数据,在方法调用之前不能调用filp()或者clear()之类的操作指针的函数
     * @param byteBuffer
     * @return
     */
    public static String readString(ByteBuffer byteBuffer){
        try {
            byte[] b = readByte(byteBuffer);
            String s = new String(b, "UTF-8");
            return s;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 一次性写入,每次从头写入,写入完成后切换读模式。
     * @param byteBuffer
     * @param data
     */
    public static void onceWrite(ByteBuffer byteBuffer,String data){
        try {
            //写之前指针复位
            byteBuffer.clear();
            byteBuffer.put(data.getBytes("utf-8"));
            byteBuffer.flip();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 可以进行多次写入,指针不复位
     * @param byteBuffer
     * @param data
     */
    public static void write(ByteBuffer byteBuffer,String data){
        try {
            byteBuffer.put(data.getBytes("utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 可以进行多次写入,指针不复位
     * @param data
     */
    public static ByteBuffer write(String data){
        ByteBuffer byteBuffer = ByteBuffer.allocate(data.getBytes().length);
        try {
            byteBuffer.put(data.getBytes("utf-8"));
            return byteBuffer;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 一次性写入,每次从头写入,写入完成后切换读模式。
     * @param data
     */
    public static ByteBuffer onceWrite(String data){
        ByteBuffer byteBuffer = ByteBuffer.allocate(data.getBytes().length);
        try {
            byteBuffer.put(data.getBytes("utf-8"));
            byteBuffer.flip();
            return byteBuffer;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
相关标签: nio buffer