通道Channel基本介绍与案例演示

73 阅读2分钟

通道Channel

基本介绍:

  1. NIO通道类似于流,但有些区别

    a. 通道可以同事进行读写,而流只能读或者写

    b. 通道可以实现异步读写数据

    c. 通道可以从缓冲区读数据,也可以写数据到缓冲区

  2. BIO中的stream 是单向的,例如FileInputStream对象只能进行读取数据的操作,而NIOs双向的 ,可以读操作,也可以写操作

  3. Channel在NIO中是一个接口

    public interface Channel extends Closeable {}
    
  4. 常用的Channel类有

    1. FileChannel
    2. ServerSocketChannel
    3. SocketChannel
    4. DatagramChannel
  5. FileChannel用于文件的数据读写;DatagramChannel用于UDP的数据读写;ServerSocketChannel用于TCP数据读写

  6. FileChannel类

    • FileChannel主要用于对本地文件进行IO操作,常用方法有
  • public int read(ByteBuffer dst) ,从通道读取数据并放到缓冲区中public int write(ByteBuffer src),把缓冲区的数据写到通道中
  • public long transferFrom(ReadableByteChannel src, long position, long count),从目标通道中复制数据到当前通道public long
  • transferTo(long position , long count, WritableByteChannel target),把数据从当前通道复制给目标通道

读入写出案例

读入写出案例.png

目标:将文件2的内容读入到文件1中去

//        创建两个 通道,一个缓冲区,将2读入的内容写出到1里面
        FileOutputStream outputStream = new FileOutputStream("d://1.txt");
        FileInputStream inputStream = new FileInputStream("d://2.txt");
        FileChannel channel1 = outputStream.getChannel();
        FileChannel channel = inputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        while (true) {
//            思路:buffer 读入1.txt channel通道,写出到channel1通道
            byteBuffer.clear();
            int read = channel.read(byteBuffer);
            System.out.println(new String(byteBuffer.array()));
            if(read==-1) { // 读入结束
                break;
            }
//            写出到channel1
            //一定要记得读入写出进行转换阿
            byteBuffer.flip();
            channel1.write(byteBuffer);
        }
//        最后进行关流操作
        outputStream.close();
        inputStream.close();

图片的拷贝

  • transferFrom的使用
//        图片拷贝
        FileInputStream inputStream = new FileInputStream("d://a.png");
        FileOutputStream outputStream = new FileOutputStream("d://b.png");

//        创建 对应的通道
        FileChannel resoursePath = inputStream.getChannel();
        FileChannel destPath = outputStream.getChannel();
        destPath.transferFrom(resoursePath, 0, resoursePath.size());

//        关闭对应的流和通道
        inputStream.close();
        outputStream.close();
        resoursePath.close();
        destPath.close();

关于Buffer与Channel的注意事项与细节

  1. ByteBuffer支持类型化的put和get,put放入的是什么数据类型,get就应该对应什么数据取出,否则报BufferUnderflowException异常
  2. 可以将一个普通Buffer转化成只读Buffer
  3. NIO提高mappedBuffer,可以让文件直接在内存(堆外的内存)中进行修改,而如何同步到文件由NIO来完成
  4. NIO还支持通过多个Buffer(Buffer数组)来完成读写操作,即SCattering 和Gathering