NIO学习笔记(二)ByteBuffer的put和get使用实例

NIO学习笔记(二)ByteBuffer的put和get使用实例

1、put(byte b)和get()方法的使用与position的自增特性

Buffer类的子类都定义了两种get(读)和put(写)操作,分别对应相对位置和绝对位置的操作

相对位置操作是指在读取或写入一个元素时,他从当前位置开始,然后将位置增加所传输的元素数。如果请求的传输超出了限制,则相对get操作抛出BufferUnderflowException,相对put操作抛出BufferOverflowException,也就是说在这两种情况下,都没有数据传输。

绝对位置采用显示元素索引,该操作不影响位置。如果索引超出限制,则绝对get操作和绝对put操作将抛出IndexOutOfBoundsException异常。

abstract ByteBuffer put(byte b)方法的作用:使用相对位置的put()操作,将给定的字节写入此缓冲区的“当前位置”,然后该位置递增。

abstract byte get()方法的作用:使用相对位置的get()操作,读取此缓冲区“当前位置”的字节,然后递增该位置。

示例代码:

public class GetPutDemo {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        System.out.println("分配了10个空间");
        System.out.println("A1 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println("传入125");
        buffer.put( (byte) 125);
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println("传入126");
        buffer.put( (byte) 126);
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println("传入127");
        buffer.put( (byte) 127);
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println("重置position");
        buffer.rewind();
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println(buffer.get());
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println(buffer.get());
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println(buffer.get());
        System.out.println("A2 capacity=" +
                buffer.capacity() + " limit=" + buffer.limit() +
                " position=" + buffer.position());
        System.out.println(buffer.get());
        byte[] getByteArray = buffer.array();
        System.out.println(Arrays.toString(getByteArray));
    }
}

从运行结果上来看,在执行相对位置的读写操作以后,位置(position)呈现递增的状态,位置自动移动到下一个位置上,以便进行下一次读或者写的操作。

2、put(byte[] src , int offset , int length)和get(byte[] dst , int offset , int length)方法的使用

put(byte[] src , int offset , int length):相对批量的put方法,此方法将把给定原数组中的字节传输到此缓冲区当前位置中。如果要从数组中复制的字节多于此缓冲区中,则不传输字节并且抛出BufferOverflowException异常。否则,此方法将给定数组中的length个字节复制到此缓冲区中,将数组中给定offset偏移量位置的数据复制到缓冲区的当前位置,从数组中复制的元素个数为length。换句话说,调用此方法的形式为dst.put(src , offset , length),效果与以下循环语句完全相同:

for(int i = offset ; i < offset+length ; i++){
    dst.put(src[i])
}

区别在于,他首先检查了是否有足够空间,这样效率可能更高。

put(byte[] src , int offset , int length):相对get批量的方法,此方法将此缓冲区当前位置的字节传输到给定的目标数组。如果此缓冲区剩下的字节少于满足请求所需要的字节,则不传输且抛出BufferUnderflowException异常。否则,此方法将此缓冲区中的length个字节复制到给定数组中。从此缓冲区的当前位置和数组给定的偏移量位置开始复制。然后此缓冲区的位置将增加length。换句话来说,调用此方法的形式为src.get(dst,offset,length),效果与这条语句完全相同:

for(int i = offset ; i < offset+length ; i++){
	dst[i] = src.get();
}

区别在于,他首先检查了是否有足够空间,这样效率可能更高。

下面我们来看一段示例代码:

public class PutGetDemo2 {
    public static void main(String[] args) {
        byte[] array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        byte[] array2 = {55, 66, 77, 88};
        //分配10个空间
        ByteBuffer buffer = ByteBuffer.allocate(10);
        //将array1传入缓冲区
        buffer.put(array1);
        //位置定位到2
        buffer.position(2);
        //array2的数据传入缓冲区的2到4号位置
        buffer.put(array2,1,3);
        //打印
        System.out.println(Arrays.toString(buffer.array()));
        byte[] array3 = new byte[buffer.capacity()];
        //将缓冲区当前位置的数据传输到,目标数组的3到6号位置
        buffer.get(array3 , 3 ,4);
        System.out.println(Arrays.toString(array3));
    }
}

3、put(byte[] src )和get(byte[] dst )方法的使用

put(byte[ ] src)这个方法的作用是:将给定的原数组的所有内容存储到缓冲区当中。与该方法功能完全相同的写法为: dst.put(a,0,a.length)。

get(byte[ ] src)这个方法的作用是:此方法将此缓冲区的remaining()的字节传输到给定的目标数组。与该方法功能完全相同的写法为:src.get(a,0,a.length)。使用此方法取得的数据的数量,取决于src的长度。

put(byte[ ] src)和get(byte[ ] src)其实是调用了3个参数的put和get方法。源码如下:

 public final ByteBuffer put(byte[] src) {
     return put(src, 0, src.length);
 }
 public ByteBuffer get(byte[] dst) {
     return get(dst, 0, dst.length);
 }

注意:以下会出现异常的情况

public final ByteBuffer put(byte[] src)

1)remaining()小于数组的length,出现异常

public ByteBuffer get(byte[] dst)

1)remaining()小于数组的length,出现异常

4、put(int index , byte b)和get(int index)方法的使用

put(int index , byte b),绝对put方法,此方法的作用是:将给定的字节写入此缓冲区的给定索引位置。

get(int index),绝对get方法,此方法的作用是:读取指定位置索引处的字节

示例代码:

public class PutGetDemo3 {
    public static void main(String[] args) {
        byte[] array1 = {1,2,3,4,5,6,7,8,9};
        ByteBuffer buffer = ByteBuffer.allocate(10);
        buffer.put(array1);
        buffer.put(2,(byte) 125);
        System.out.println(buffer.get(2));
        buffer.position(0);
        byte[] array2 = new byte[buffer.capacity()];
        buffer.get(array2 , 0 , array2.length);
        System.out.println(Arrays.toString(array2));
    }
}

5、put(ByteBuffer src)方法的使用

put(ByteBuffer src)这个方法的作用是:此方法给定的原缓冲区的剩余字节传输到此缓冲区的当前位置中。如果原缓冲区中的剩余字节多于此缓冲区的剩余字节,则不传输并抛出BufferOverflowException异常。否则,就将给定缓冲区的剩余字节复制到此缓冲区中。

public class PutDemo {
    public static void main(String[] args) {
        byte[] array1 = {1,2,3,4,5,6,7,8};
        ByteBuffer buffer1 = ByteBuffer.wrap(array1);

        byte[] array2 = {55,66,77};
        ByteBuffer buffer2 = ByteBuffer.wrap(array2);

        buffer1.position(4);
        buffer2.position(1);

        buffer1.put(buffer2);
        System.out.println("buffer1被改变"+buffer1.position());
        System.out.println("buffer2被改变"+buffer2.position());

        System.out.println(Arrays.toString(buffer1.array()));
        System.out.println(Arrays.toString(buffer2.array()));
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Java中的FileChannel类和ByteBuffer类来实现NIO操作,可以提高文件读取效率。以下是一个使用NIO读取文件的示例代码: ```java import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class NIOFileReader { public static void main(String[] args) throws IOException { // 打开文件通道 FileChannel fileChannel = new FileInputStream(new File("file.txt")).getChannel(); // 创建一个缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); // 从文件通道读取数据到缓冲区 while (fileChannel.read(buffer) != -1) { // 切换读写模式 buffer.flip(); // 读取缓冲区中的数据 while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } // 清空缓冲区 buffer.clear(); } // 关闭文件通道 fileChannel.close(); } } ``` 在这个示例中,我们首先打开文件通道,然后创建一个ByteBuffer缓冲区来存储读取到的数据。在循环中,我们使用FileChannel的read()方法将数据读取到缓冲区中,然后使用ByteBuffer的flip()方法切换读写模式,从而可以读取缓冲区中的数据。最后使用ByteBuffer的clear()方法清空缓冲区。 需要注意的是,在使用FileChannel读取数据时,需要先将数据读取到缓冲区中,然后再从缓冲区中读取数据。同时,由于缓冲区的大小是有限的,因此需要在循环中反复读取数据,直到读取到文件的末尾为止。 除了读取数据外,FileChannel还可以用于写入数据、截取文件、移动文件指针等操作。使用Java中的NIO操作可以提高文件读取效率,适用于需要频繁读写文件的场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值