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

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

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

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

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

@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 
--------------
�����Ǹ�������