前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NIO学习三-Channel

NIO学习三-Channel

作者头像
路行的亚洲
发布2020-07-17 10:22:08
4890
发布2020-07-17 10:22:08
举报
文章被收录于专栏:后端技术学习

在学习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("学无止境\r\n".getBytes());
                    try {
                        fileChannel.write(buffer);
                    } catch (IOException e) {
                        log.error("写入数据失败:{}" + e.getMessage());
                    }
                }
            };

            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    ByteBuffer buffer = ByteBuffer.wrap("山高人为峰\r\n".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("学无止境\r\n".getBytes());
                    ByteBuffer buffer2 = ByteBuffer.wrap("吾生有崖亦无涯\r\n".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("山高人为峰\r\n".getBytes());
                    ByteBuffer buffer2 = ByteBuffer.wrap("前行有路\r\n".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。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端技术学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档