Java NIO(5) - 通道(2)分散 和 聚集

95 阅读1分钟

3.9 分散(Scatter) 和 聚集(Gather)

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

image.png

注意:按照缓冲区的顺序,从 Channel 中读取的数据依次将 Buffer 填满.

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

image.png

注意:按照缓冲区的顺序,写入 position 和 limit 之间的数据到 Channel 。

    /**
     * 分散和聚集
     */
    @Test
    public void test04() {
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        FileChannel readChannel = null;
        FileChannel writeChannel = null;
        try {
            raf1 = new RandomAccessFile("1.txt", "rw");
            //1.获取通道
            readChannel = raf1.getChannel();

            //2.分配指定大小的缓冲区
            ByteBuffer bb1 = ByteBuffer.allocate(100);
            ByteBuffer bb2 = ByteBuffer.allocate(1024);

            //3.分散读取
            ByteBuffer[] bbs = {bb1, bb2};
            readChannel.read(bbs);

            for (ByteBuffer bb : bbs) {
                bb.flip();
            }
            System.out.println(new String(bbs[0].array(), 0, bbs[0].limit()));
            System.out.println("----------------------------");
            System.out.println(new String(bbs[1].array(), 0, bbs[1].limit()));

            //4. 聚集写入
            raf2 = new RandomAccessFile("2.txt", "rw");
            writeChannel = raf2.getChannel();
            writeChannel.write(bbs);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf1 != null) {
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (raf2 != null) {
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (readChannel != null) {
                try {
                    readChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (writeChannel != null) {
                try {
                    writeChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 字符集
     */
    @Test
    public void test05() {
        Charset cs1 = Charset.forName("GBK");
        //获取编码器
        CharsetEncoder ce = cs1.newEncoder();
        //获取解码器
        CharsetDecoder cd = cs1.newDecoder();

        CharBuffer cb = CharBuffer.allocate(1024);
        cb.put("哈哈");
        cb.flip();
        try {
            //编码
            ByteBuffer bb = ce.encode(cb);

            for (int i = 0; i < cb.length(); i++) {
                System.out.println(bb.get());
            }

            //解码
            bb.flip();
            CharBuffer cb2 = cd.decode(bb);
            System.out.println(cb2.toString());

            Charset cs2 = Charset.forName("GBK");
            System.out.println("------------");
            bb.flip();
            CharBuffer cBuf3 = cs2.decode(bb);
            System.out.println(cBuf3.toString());
        } catch (CharacterCodingException e) {
            e.printStackTrace();
        }
    }

3.10 FileChannel 的常用方法

image.png