NIO学习三-Channel

2020-07-17 10:22:08 浏览数 (3)

在学习NIO时,ByteBuffer、Channel、Selector三个组件是必须了解的。前面我们说到ByteBuffer是作为缓冲区进行数据的存放或者获取。通常我们需要进行flip翻转操作,但是这个在Netty中,有一个更为强大的类可以替代ByteBuf,其不需要进行翻转,也可以进行读写的双向操作。要将数据打包到缓冲区中,通常需要使用通道,而通道作为传输数据的载体,也即它可以使数据从一端到另一端,因此就必须进行了解。

Channel中,我们也看到其子类有很多,通常都是用于读写操作的。其中ByteChannel可以进行读写操作,也即可以进行双向操作。

操作过程:首先创建流对象,有了流对象获取通道,然后准备好写入或者读入通道的bytebuffer信息,使用通道写入或者读入。写入或者读入之后,不要忘记关闭通道、关闭流。这里介绍简单的读写操作,更为详细的可以去参考jdk的api。

1.进行写操作

代码语言:javascript复制
/**
 * 进行channel的学习:
 * nio中buffer、channel、selector三个组件,其中buffer提供了读写操作的条件(缓冲区),而channel提供通道,
 * 而selector则是多路复用的技术
 * channel通道:用来传输数据的通道
 * 我们先来看FileChannel:主要是读取、写入、映射和操作文件的通道,该通道永远是阻塞的操作
 * 先看写操作 int write(ByteBuffer src);
 */
@Slf4j
public class ChannelWriteTest {
    public static void main(String[] args) throws Exception {
        //从通道的当前位置开始写入
        fileChannelTest1();
        System.out.println("================");
        //从remaining写入通道
        fileChannelTest2();
        System.out.println("================");
        //write方法具有同步性
        fileChennelTest3();
    }

    //write方法具有同步性
    private static void fileChennelTest3() throws InterruptedException, IOException {
        //fileChannel中的write方法的同步性
        FileOutputStream fos = new FileOutputStream(new File("test2.txt"));
        FileChannel fileChannel = fos.getChannel();
        //启动两个线程
        for (int i = 0; i < 10; i  ) {
            Thread thread1 = new Thread() {
                @Override
                public void run() {
                    ByteBuffer buffer = ByteBuffer.wrap("学无止境rn".getBytes());
                    try {
                        fileChannel.write(buffer);
                    } catch (IOException e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };

            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    ByteBuffer buffer = ByteBuffer.wrap("山高人为峰rn".getBytes());
                    try {
                        fileChannel.write(buffer);
                    } catch (IOException e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };

            thread1.start();
            thread2.start();
        }
        Thread.sleep(3000);
        fileChannel.close();
        fos.close();
    }

    //从remaining写入通道
    private static void fileChannelTest2() throws IOException {
        //创建流对象、获取通道,进行字节包装,使用通道进行写入
        FileOutputStream fos = new FileOutputStream(new File("test1.txt"));
        FileChannel fileChannel = fos.getChannel();
        try {
            //子节1:abcde
            ByteBuffer buffer1 = ByteBuffer.wrap("abcde".getBytes());
            //子节2:12345
            ByteBuffer buffer2 = ByteBuffer.wrap("12345".getBytes());
            //首先写入abcde,此时buffer2的当前位置是1,因此下一个位置是2,同时上界是3,因此2、3位置会放入,因此会将2、3放入到
            //abcde中,变成 ab23e,因此同时通道的位置设置当前位置是2,因此下一个位置是3,因此其位置为2 2=4
            fileChannel.write(buffer1);
            buffer2.position(1);
            buffer2.limit(3);
            fileChannel.position(2);
            fileChannel.write(buffer2);
            System.out.println(fileChannel.position());
        } catch (Exception e) {
            log.error("写入数据失败:{}"   e.getMessage());
        }
        //关闭流、通道
        fileChannel.close();
        fos.close();
    }

    //从通道的当前位置开始写入
    private static void fileChannelTest1() throws Exception {
        //创建流对象
        FileOutputStream fos = new FileOutputStream(new File("test.txt"));
        //获取通道
        FileChannel fileChannel = fos.getChannel();
        try {
            //将byte包装成byteBuffer,使用fileChannel的write方法将其写入到file中
            ByteBuffer buffer = ByteBuffer.wrap("abcde".getBytes());
            //写入之前的位置是0
            System.out.println("A fileChannel.postion()="   fileChannel.position());
            //写入数据
            System.out.println("write() 1 返回值:"   fileChannel.write(buffer));
            //当前位置变成5
            System.out.println("B fileChannel.postion()="   fileChannel.position());

            //此时的文件通道的位置是2
            fileChannel.position(2);
            //将其buffer的位置变成0
            buffer.rewind();
            //然后往文件里面写数据
            System.out.println("write() 2 返回值:"   fileChannel.write(buffer));
            //可以看到文件通道的位置变成了7
            System.out.println("C fileChannel.postion()="   fileChannel.position());
        } catch (IOException e) {
            log.error("写入数据失败:{}"   e.getMessage());
        }
        //关通道、流
        fileChannel.close();
        fos.close();
    }
}

2.进行读操作

代码语言:javascript复制
/**
 * fileChannel读操作:int read(ByteBuffer dst);
 * 将字节序列从此通道的当前位置读入给定的缓冲区的当前位置
 * int中返回的值:
 * 正数表示从通道的当前位置向bytebuffer缓冲区中读的字节个数
 * 0表示从通道中没有读取任何数据
 * -1表示到达流的末端
 */
@Slf4j
public class ChannelReadTest {
    public static void main(String[] args) throws Exception {
        //使用read方法操作
        fileChannelTest1();
        System.out.println("=======================");
        //从通道的当前位置开始读取
        fileChannelTest2();
        System.out.println("=======================");
        //将字节放入ByteBuffer当前位置
        fileChannelTest3();
        System.out.println("=======================");
        fileChannelTest4();
        System.out.println("=======================");
        //从通道读取的数据大于缓冲区容量
        fileChannelTest5();
        System.out.println("=======================");
        //从通道读取的字节放入缓冲区的remaining空间中
        fileChannelTest6();

    }

    private static void fileChannelTest6() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
        byteBuffer.position(1);
        byteBuffer.limit(3);
        fileChannel.read(byteBuffer);
        fileChannel.close();
        fis.close();
        byteBuffer.rewind();
        for (int i = 0; i < byteBuffer.limit(); i  ) {
            byte eachByte = byteBuffer.get();
            if (eachByte == 0) {
                System.out.println("空格");
            } else {
                System.out.println((char) eachByte);
            }
        }
    }

    private static void fileChannelTest5() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(3);
        System.out.println("A"   fileChannel.position());
        fileChannel.read(byteBuffer);
        System.out.println("B"   fileChannel.position());
        fileChannel.close();
        fis.close();
        byteBuffer.rewind();

        for (int i = 0; i < byteBuffer.limit(); i  ) {
            System.out.println((char) byteBuffer.get());
        }
    }

    private static void fileChannelTest4() throws InterruptedException, IOException {
        FileInputStream fis = new FileInputStream(new File("test4.txt"));
        FileChannel fileChannel = fis.getChannel();
        for (int i = 0; i < 1; i  ) {
            Thread thread1 = new Thread() {
                @Override
                public void run() {
                    try {
                        ByteBuffer byteBuffer = ByteBuffer.allocate(5);
                        int readLength = fileChannel.read(byteBuffer);
                        while (readLength != -1) {
                            byte[] getByte = byteBuffer.array();
                            System.out.println(new String(getByte, 0, readLength));
                            byteBuffer.clear();
                            readLength = fileChannel.read(byteBuffer);
                        }
                    } catch (Exception e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };
            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    try {
                        ByteBuffer byteBuffer = ByteBuffer.allocate(5);
                        int readLength = fileChannel.read(byteBuffer);
                        while (readLength != -1) {
                            byte[] getByte = byteBuffer.array();
                            System.out.println(new String(getByte, 0, readLength));
                            byteBuffer.clear();
                            readLength = fileChannel.read(byteBuffer);
                        }
                    } catch (Exception e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };
            thread1.start();
            thread2.start();

        }
        Thread.sleep(3000);
        fileChannel.close();
        fis.close();
    }

    private static void fileChannelTest3() throws IOException {
        FileInputStream fos = new FileInputStream(new File("test3.txt"));
        FileChannel fileChannel = fos.getChannel();
        //当前位置为2,因此下一个位置为3
        fileChannel.position(2);
        //而长度为5,因此打印结果:3 4 5 空格位置  空格位置
        ByteBuffer byteBuffer = ByteBuffer.allocate(5);
        fileChannel.read(byteBuffer);
        byteBuffer.position(3);
        //向byteBuffer读入cd
        fileChannel.read(byteBuffer);
        byte[] getByteArray = byteBuffer.array();
        for (int i = 0; i < getByteArray.length; i  ) {
            if (getByteArray[i] == 0) {
                System.out.println(" 空格 ");
            } else {
                System.out.println((char) getByteArray[i]);
            }
        }
        fileChannel.close();
        fos.close();
    }

    //从通道的当前位置开始读取
    private static void fileChannelTest2() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test3.txt"));
        FileChannel fileChannel = fis.getChannel();
        //当前位置为2,因此下一个位置为3
        fileChannel.position(2);
        //而长度为5,因此打印结果:3 4 5 空格位置  空格位置
        ByteBuffer byteBuffer = ByteBuffer.allocate(5);
        fileChannel.read(byteBuffer);
        byte[] getByteArray = byteBuffer.array();
        for (int i = 0; i < getByteArray.length; i  ) {
            System.out.println((char) getByteArray[i]);
        }
        fileChannel.close();
        fis.close();
    }

    //使用read方法操作
    private static void fileChannelTest1() throws Exception {
        FileInputStream fis = new FileInputStream(new File("test3.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(5);
        int readLength = fileChannel.read(byteBuffer);
        System.out.println(readLength);
        //由于byteBuffer没有remaing剩余空间,因此返回的就是0
        readLength = fileChannel.read(byteBuffer);
        System.out.println(readLength);
        byteBuffer.clear();
        readLength = fileChannel.read(byteBuffer);
        //到达流的末尾值为-1
        System.out.println(readLength);
        byteBuffer.clear();
        fileChannel.close();
        fis.close();
    }
}

3.进行批量写操作

代码语言:javascript复制
/**
 * 进行批量写操作 long write(ByteBuffer[] src)
 * 将每个缓冲区的remaining字节序列写入此通道的当前位置
 */
@Slf4j
public class ChannelBatchWriteTest {
    public static void main(String[] args) throws Exception {
        //进行批量写操作
        fileChannelBatchWriteTest();
        fileChannelBatchWriteTest2();
        fileChannelBatchWriteTest3();
    }

    private static void fileChannelBatchWriteTest() throws IOException {
        FileOutputStream fos = new FileOutputStream(new File("a.txt"));
        FileChannel fileChannel = fos.getChannel();
        fileChannel.write(ByteBuffer.wrap("123456".getBytes()));
        fileChannel.position(3);

        ByteBuffer byteBuffer1 = ByteBuffer.wrap("000001".getBytes());
        ByteBuffer byteBuffer2 = ByteBuffer.wrap("000002".getBytes());
        //将多个单的bytebuffer放入byteBuffers中,再写入
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer1,byteBuffer2};
        fileChannel.write(byteBuffers);

        fileChannel.close();
        fos.close();
    }

    private static void fileChannelBatchWriteTest2() throws IOException {
        FileOutputStream fos = new FileOutputStream(new File("b.txt"));
        FileChannel fileChannel = fos.getChannel();
        fileChannel.write(ByteBuffer.wrap("123456".getBytes()));
        fileChannel.position(3);

        ByteBuffer byteBuffer1 = ByteBuffer.wrap("abcde1".getBytes());
        ByteBuffer byteBuffer2 = ByteBuffer.wrap("uxdax2".getBytes());
        //将多个单的bytebuffer放入byteBuffers中,再写入
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer1,byteBuffer2};

        byteBuffer1.position(1);
        byteBuffer1.limit(3);

        byteBuffer2.position(2);
        byteBuffer2.limit(4);

        fileChannel.write(byteBuffers);

        fileChannel.close();
        fos.close();
    }

    //write方法具有同步性
    private static void fileChannelBatchWriteTest3() throws InterruptedException, IOException {
        //fileChannel中的write方法的同步性
        FileOutputStream fos = new FileOutputStream(new File("c.txt"));
        FileChannel fileChannel = fos.getChannel();
        //启动两个线程
        for (int i = 0; i < 10; i  ) {
            Thread thread1 = new Thread() {
                @Override
                public void run() {
                    ByteBuffer buffer1 = ByteBuffer.wrap("学无止境rn".getBytes());
                    ByteBuffer buffer2 = ByteBuffer.wrap("吾生有崖亦无涯rn".getBytes());
                    try {
                        ByteBuffer[] byteBuffers = new ByteBuffer[]{buffer1,buffer2};
                        fileChannel.write(byteBuffers);
                    } catch (IOException e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };

            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    ByteBuffer buffer1 = ByteBuffer.wrap("山高人为峰rn".getBytes());
                    ByteBuffer buffer2 = ByteBuffer.wrap("前行有路rn".getBytes());
                    ByteBuffer[] byteBuffers = new ByteBuffer[]{buffer1,buffer2};

                    try {
                        fileChannel.write(byteBuffers);
                    } catch (IOException e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };

            thread1.start();
            thread2.start();
        }
        Thread.sleep(3000);
        fileChannel.close();
        fos.close();
    }



}

4.进行批量读操作

代码语言:javascript复制
/**
 * 进行批量读操作 long read(ByteBuffer[] dsts)
 */
@Slf4j
public class ChannelBatchReadTest {
    public static void main(String[] args) throws Exception {
        //进行批量读操作
        fileChannelBatchReadTest1();
        System.out.println("==========");
        //从通道的当前位置开始读取
        fileChannelBatchReadTet2();
        System.out.println("==========");
        //进行批量读,将字节放入ByteBuffer当前位置
        fileChannelReadBatchTest3();
        System.out.println("==========");
        //批量读的同步性
        fileChannelReadBatchTest4();

        //从通道读取的数据大于缓冲区容量
        fileChannelBatchReadTest5();

        //从通道的字节放入缓冲去的remaining空间中
        fileChannelBatchReadTest6();
    }

    private static void fileChannelBatchReadTest6() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test1.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(7);
        byteBuffer.position(1);
        byteBuffer.limit(3);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(7);
        byteBuffer.position(2);
        byteBuffer.limit(4);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
        fileChannel.read(byteBuffers);
        fileChannel.close();
        fis.close();

        byteBuffer.rewind();
        byteBuffer1.rewind();

        for (int i = 0; i < byteBuffers.length; i  ) {
            ByteBuffer byteBuffer2 = byteBuffers[i];
            byte[] getByte = byteBuffer2.array();
            for (int j = 0; j < getByte.length; j  ) {
                if (getByte[j] == 0) {
                    System.out.println("空格");
                } else {
                    System.out.println((char) getByte[j]);
                }
                System.out.println();
            }
        }
    }

    private static void fileChannelBatchReadTest5() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test1.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(2);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
        System.out.println("A "   fileChannel.position());
        long readLength = fileChannel.read(byteBuffers);
        System.out.println("B "   fileChannel.position()   "readLength="   readLength);
        fileChannel.close();
        fis.close();

        byteBuffer.rewind();
        byteBuffer1.rewind();
        byteBuffer.position(1);
        for (int i = 0; i < byteBuffers.length; i  ) {
            byte[] getByte = byteBuffers[i].array();
            for (int k = 0; k < getByte.length; k  ) {
                System.out.print((char) getByte[k]);
            }
            System.out.println();
        }
    }

    private static void fileChannelReadBatchTest4() throws Exception {
        FileInputStream fis = new FileInputStream(new File("d.txt"));
        FileChannel fileChannel = fis.getChannel();
        for (int i = 0; i < 10; i  ) {
            Thread thread1 = new Thread() {
                @Override
                public void run() {
                    try {
                        ByteBuffer byteBuffer = ByteBuffer.allocate(8);
                        ByteBuffer byteBuffer1 = ByteBuffer.allocate(8);
                        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
                        long readLength = fileChannel.read(byteBuffers);
                        while (readLength != -1) {
                            synchronized (ChannelBatchReadTest.class) {
                                for (int j = 0; j < byteBuffers.length; j  ) {
                                    byte[] getByte = byteBuffers[j].array();
                                    for (int k = 0; k < getByte.length; k  ) {
                                        System.out.println((char) getByte[k]);
                                    }
                                }
                            }
                            byteBuffer.clear();
                            byteBuffer1.clear();
                            readLength = fileChannel.read(byteBuffers);
                        }
                    } catch (Exception e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };
            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    try {
                        ByteBuffer byteBuffer = ByteBuffer.allocate(8);
                        ByteBuffer byteBuffer1 = ByteBuffer.allocate(8);
                        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
                        long readLength = fileChannel.read(byteBuffers);
                        while (readLength != -1) {
                            synchronized (ChannelBatchReadTest.class) {
                                for (int j = 0; j < byteBuffers.length; j  ) {
                                    byte[] getByte = byteBuffers[j].array();
                                    for (int k = 0; k < getByte.length; k  ) {
                                        System.out.println((char) getByte[k]);
                                    }
                                }
                            }
                            byteBuffer.clear();
                            byteBuffer1.clear();
                            readLength = fileChannel.read(byteBuffers);
                        }
                    } catch (Exception e) {
                        log.error("写入数据失败:{}"   e.getMessage());
                    }
                }
            };
            thread1.start();
            thread2.start();
        }
        Thread.sleep(3000);
        fileChannel.close();
        fis.close();

    }


    private static void fileChannelReadBatchTest3() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test1.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(2);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
        byteBuffer.position(1);
        fileChannel.read(byteBuffers);
        for (int i = 0; i < byteBuffers.length; i  ) {
            byte[] getByte = byteBuffers[i].array();
            for (int j = 0; j < getByte.length; j  ) {
                if (getByte[j] == 0) {
                    System.out.println("空格");
                } else {
                    System.out.println((char) getByte[j]);
                }
                System.out.println();
            }
            fileChannel.close();
            fis.close();
        }
    }

    private static void fileChannelBatchReadTet2() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test1.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(2);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
        fileChannel.read(byteBuffers);
        for (int i = 0; i < byteBuffers.length; i  ) {
            byte[] getByte = byteBuffers[i].array();
            for (int j = 0; j < getByte.length; j  ) {
                System.out.println((char) getByte[j]);
            }
            System.out.println();
        }
        fileChannel.close();
        fis.close();
    }

    private static void fileChannelBatchReadTest1() throws IOException {
        FileInputStream fis = new FileInputStream(new File("test1.txt"));
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(2);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};
        long readLength = fileChannel.read(byteBuffers);
        System.out.println(readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        readLength = fileChannel.read(byteBuffers);
        System.out.println(readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        readLength = fileChannel.read(byteBuffers);
        System.out.println(readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        readLength = fileChannel.read(byteBuffers);
        System.out.println(readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        fileChannel.close();
        fis.close();
    }
}

5.进行部分批量写操作

代码语言:javascript复制
/**
 * 进行部分批量写操作 long write(ByteBuffer[] srcs,int offset,int length)
 * 以指定缓冲数组的offset下标开始,向后使用length个字节缓冲区,
 * 再将每个缓冲区的remaining剩余字节子序列写入此通道的当前位置
 */
public class ChannelPartBatchWriteTest {
    public static void main(String[] args) throws Exception {
        fileChannelPartBatchWriteTest1();
        fileChannelPartBatchWriteTest2();
    }

    private static void fileChannelPartBatchWriteTest1() throws IOException {
        FileOutputStream fos = new FileOutputStream(new File("test.txt"));
        FileChannel fileChannel = fos.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.wrap("abcde".getBytes());
        ByteBuffer byteBuffer1 = ByteBuffer.wrap("12345".getBytes());

        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer,byteBuffer1};

        fileChannel.write(ByteBuffer.wrap("QSDXXX".getBytes()));
        fileChannel.position(2);

        fileChannel.write(byteBuffers,0,2);

        fileChannel.close();
        fos.close();
    }

    private static void fileChannelPartBatchWriteTest2() throws IOException {
        FileOutputStream fos = new FileOutputStream(new File("test.txt"));
        FileChannel fileChannel = fos.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.wrap("abcde".getBytes());
        ByteBuffer byteBuffer1 = ByteBuffer.wrap("12345".getBytes());

        byteBuffer1.position(1);
        byteBuffer1.limit(3);
        ByteBuffer byteBuffer3 = ByteBuffer.wrap("dwsrdf".getBytes());
        byteBuffer3.position(2);
        byteBuffer3.limit(4);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer,byteBuffer1,byteBuffer3};

        fileChannel.write(byteBuffers,1,2);
        fileChannel.position(2);

        fileChannel.write(byteBuffers,0,2);

        fileChannel.close();
        fos.close();
    }

}

6.进行部分批量读操作

代码语言:javascript复制
/**
 * 进行批量读操作 long read(ByteBuffer[] dsts,int offset,int length)
 */
public class ChannelPartBatchReadTest {
    public static void main(String[] args) throws Exception{
        fileChannelPartBatchReadTest1();
        System.out.println("===============");
        fileChannelPartBatchReadTest2();
    }

    private static void fileChannelPartBatchReadTest1() throws IOException {
        FileInputStream fis = new FileInputStream(new File("e.txt"));
        FileChannel fileChannel = fis.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(2);

        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};

        long readLength = fileChannel.read(byteBuffers,0,2);
        System.out.println("readLength="   readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        readLength = fileChannel.read(byteBuffers,0,2);
        System.out.println("readLength="   readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        readLength = fileChannel.read(byteBuffers,0,2);
        System.out.println("readLength="   readLength);
        byteBuffer.clear();
        byteBuffer1.clear();

        fileChannel.close();
        fis.close();
    }

    private static void fileChannelPartBatchReadTest2() throws IOException {
        FileInputStream fis = new FileInputStream(new File("e.txt"));
        FileChannel fileChannel = fis.getChannel();
        fileChannel.position(2);

        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(2);

        ByteBuffer[] byteBuffers = new ByteBuffer[]{byteBuffer, byteBuffer1};

        fileChannel.read(byteBuffers,0,2);

        for (int i = 0; i < byteBuffers.length; i  ) {
            byte[] getByte = byteBuffers[i].array();
            for (int k = 0; k < getByte.length; k  ) {
                System.out.print((char) getByte[k]);
            }
            System.out.println();
        }
        fileChannel.close();
        fis.close();
    }
}

今天就介绍到这里,下一篇我们学习多路复用必备组件Selector。

0 人点赞