NIO的/分散读取和聚集写入

本文介绍Java NIO中分散读取与聚集写入的概念及应用实例,展示了如何通过多个缓冲区进行高效的数据读写操作,并探讨了字符集编码与解码的相关问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分散读取(Scattering Reads)是指从 Channel 中读取的数据“分散”到多个 Buffer 中。


聚集写入(Gathering Writes)是指将多个 Buffer 中的数据“聚集”到 Channel。


@Test
//分散读取(scattering reads): 将通道中的数据分散读取到Buffer
//聚集写入(gathering writes): 将多个缓冲区数据写入到通道中
public void test3() throws FileNotFoundException {
    FileChannel channel1 = null;
    FileChannel channel = null;
    try {
        RandomAccessFile accessFile = new RandomAccessFile("d:/1.txt", "rw");
        //获取通道
        channel = accessFile.getChannel();

        //指定buffer
        ByteBuffer buffer1 = ByteBuffer.allocate(100);
        ByteBuffer buffer2 = ByteBuffer.allocate(100);

        ByteBuffer[] buffers = {buffer1, buffer2};

        channel.read(buffers);
        for (ByteBuffer buffer : buffers) {
            buffer.flip(); //切换读模式
        }
        //从通道中读取数据
        System.out.println(new String(buffers[0].array(), "gb2312"));
        System.out.println(new String(buffers[1].array(), "gb2312"));

        //聚集写入
        RandomAccessFile accessFile1 = new RandomAccessFile("d:/2.txt", "rw");
        channel1 = accessFile1.getChannel();
        channel1.write(buffers);


    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            channel.close();
            channel1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
字符集的问题

@Test
//字符集
//查看可用的字符集
public void testCharset() {
    Map<String, Charset> sortedMap = Charset.availableCharsets();
    Set<Map.Entry<String, Charset>> entries = sortedMap.entrySet();
    for (Map.Entry<String, Charset> entry : entries) {
        System.out.println(entry.getKey() + "---->" + entry.getValue());
    }
}

@Test
public void test4() { //格式化代码快捷键 ctrl + alt + l
    try {
        //指定字符集
        Charset gbk = Charset.forName("GBK");

        //获取编码器
        CharsetEncoder charsetEncoder = gbk.newEncoder();
        //获取解码器
        CharsetDecoder charsetDecoder = gbk.newDecoder();

        String s = "今天是个好日子";
        CharBuffer buffer = CharBuffer.allocate(14);
        buffer.put(s);
        //使用编码器编码

        buffer.flip();//切换读模式
        //其实就是把CharBuffer转换成了ByteBuffer,中间要经过字符编码
        ByteBuffer byteBuffer = charsetEncoder.encode(buffer);
        for (int i = 0; i < byteBuffer.limit(); i++) {
            System.out.println(byteBuffer.get());

        }
        System.out.println("--------------");

        //使用 解码器解码
        byteBuffer.rewind(); //重读
        CharBuffer decode = charsetDecoder.decode(byteBuffer);
        System.out.println(decode.toString());
        System.out.println("--------------");

        //byteBuffer.rewind();
        //使用GBk编码,使用UTF8解码
        Charset UTF8 = Charset.forName("UTF-8");

        byteBuffer.rewind();//一定要重读或者flip,否则会导致读到的是空字符
        //CharsetDecoder utf8CharSetDecoder = UTF8.newDecoder();
        CharBuffer cBuff=   UTF8.decode(byteBuffer);
        /**
         * CharsetDecoder.decode()方法
         * Checked exception thrown when an input byte sequence is not legal for given
         * charset, or an input character sequence is not a legal sixteen-bit Unicode
         * sequence.
         * 不能这样写,会抛出MalformedInputException异常,
         */
        //CharBuffer cBuff = utf8CharSetDecoder.decode(byteBuffer);

        System.out.println(cBuff.toString());

    } catch (CharacterCodingException e) {
        e.printStackTrace();
    }
}

使用GBK编码器编码,GBK解码器解码,就不会导致乱码

-67 -15 -52 -20 -54 -57 -72 -10 -70 -61 -56 -43 -41 -45 
--------------
今天是个好日子
使用GBK编码器编码,utf8解码器解码,就会导致乱码

-67 -15 -52 -20 -54 -57 -72 -10 -70 -61 -56 -43 -41 -45 
--------------
�����Ǹ�������

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值