NIO通道(channel)原理与获取

Wesley13
• 阅读 661

一、通道(Channel): 用于源节点与目标节点的连接。在java NIO中负责缓冲区中数据的传输。Channel本身不存储数据,因此需要配合缓冲区进行传输。

二、通道的主要实现类
java.nio.channels.Channel接口:
|– FileChannel
|– SocketChannel
|– ServerSocketChannel
|– DatagramChannel

三、获取通道
1、java针对支持通道的类提供了getChannel()方法
本地IO:
FileInputStream/FileOutputStream
RandomAccessFile
网络IO:
Socket
ServerSocket
DatagramSocket
2、在jdk1.7中NIO.2针对各个通道提供了静态方法open()
3、在jdk1.7中NIO.2的Files工具类的newByteChannel()

    @Test  //利用通道完成文件复制
    public void test4() throws FileNotFoundException{
        FileInputStream fis = new FileInputStream("1.mp4");
        FileOutputStream fos=new FileOutputStream("2.mp4");
        //1、获取通道
        FileChannel inChannel = fis.getChannel();
        FileChannel outChannel = fos.getChannel();
        try {
            //2、分配一个指定大小的缓冲区
            ByteBuffer buf=ByteBuffer.allocate(1024);
            //3、将通道中的数据存入缓冲区
            while(inChannel.read(buf)!=-1){
                //4、将缓冲区中的数据写入通道中
                buf.flip();  //切换读取数据模式
                outChannel.write(buf);
                buf.clear();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                outChannel.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                inChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }   
        }
    }


    @Test  //使用直接缓冲区完成文件的复制
    public void test5() throws IOException{
        FileChannel inChannel=FileChannel.open(Paths.get("1.mp4"),StandardOpenOption.READ);
        FileChannel outChannel=FileChannel.open(Paths.get("2.mp4"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
        //内存映射文件
        MappedByteBuffer inMappedBuf=inChannel.map(MapMode.READ_ONLY,0,inChannel.size());
        MappedByteBuffer outMappedBuf=outChannel.map(MapMode.READ_WRITE,0,inChannel.size());
        //直接对缓冲区进行数据的读写操作
        byte[] dst=new byte[inMappedBuf.limit()];
        inMappedBuf.get(dst);
        outMappedBuf.put(dst);
        outChannel.close();
        inChannel.close();
    }

四、通道之间的数据传输

    @Test  // 通道之间的数据传输(直接缓冲区)
    public void test6() throws IOException{
        FileChannel inChannel=FileChannel.open(Paths.get("1.mp4"),StandardOpenOption.READ);
        FileChannel outChannel=FileChannel.open(Paths.get("2.mp4"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
        //inChannel.transferTo(0,inChannel.size(),outChannel); //二选一即可
        outChannel.transferFrom(inChannel,0,inChannel.size());
        outChannel.close();
        inChannel.close();
    }
点赞
收藏
评论区
推荐文章
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Netty(二)
一、先讲下NIO编程。NIO(NonblockI/O),亦叫做非阻塞I/O与Socket类和ServerSocket类相对应,NIO也提供了SocketChannel和ServerSocketChannel两种不同的套接字通道实现。1 缓冲区Buffer这里首先介绍缓冲区的概念,NIO和原I/O的一个重要区别就是NIO库中,所有数据都是用缓
Wesley13 Wesley13
3年前
JAVA NIO(一)
1NIO概述1.1NIO(newIO)是一个可以替代javaIOAPI的API,NIO提供了与标准IO不同的工作方式,标准IO是基于字节流和字符流进行操作的,而NIO是基于channel和Buffer进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写到通道中,方式如例图示,JAVANIO的几个核心组成部分是channels,Buf
Wesley13 Wesley13
3年前
Java NIO 三大组件之 Channel
JavaNIO之Channel一、什么是ChannelChannel用于源节点(例如磁盘)与目的节点的连接,它可以进行读取,写入,映射和读/写文件等操作。在JavaNIO中负责缓冲区中数据的传输。Channel本省不存储数据,因此需要配合缓冲区进行传输。(个人理解其实就是相当于保存两通信地间的
Wesley13 Wesley13
3年前
Java.NIO编程一览笔录
Java标准IO与JavaNIO的简单差异示意: Java标准IOJavaNIOAPI调用简单复杂底层实现面向流(stream),单向面向通道(channel),释放CPU、内存压力成效同步阻塞同步非阻塞数据窥视阻塞读取,要么足够,要么没有使用缓冲区(Buffer),读数据时需要检查是否
Wesley13 Wesley13
3年前
NIO阻塞与非阻塞IO
一、使用NIO完成网络通信的三个核心1、通道(Channel):负责连接java.nio.channels.Channel接口|–SelectableChannel|–SocketChannel|–ServerChannel|–DatagramChannel|–Pipe.SinkChannel|–Pipe
Stella981 Stella981
3年前
Netty之缓冲区ByteBuf解读(一)
!(https://oscimg.oschina.net/oscnet/up6de4d71f462d9846befe00ec6505125a928.JPEG)\Netty在数据传输过程中,会使用缓冲区设计来提高传输效率。虽然,Java在NIO编程中已提供ByteBuffer类进行使用,但是在使用过程中,其编码方式相对来说不太友好,也
Wesley13 Wesley13
3年前
Java NIO编程学习总结
目录1、同步,异步,阻塞,非阻塞的理解2、什么是BIO、NIO、AIO3、javaNIO常用类和方法介绍3.1.缓冲区Buffer3.2.通道Channel3.2.1FileChannel3.2.2SocketChan
Wesley13 Wesley13
3年前
Java NIO系列教程(五) 通道之间的数据传输
在JavaNIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel(译者注:channel中文常译作通道)传输到另外一个channel。transferFrom()FileChannel的transferFrom()方法可以将数据从源通道传输到FileChannel中(译者注:这个方法在JDK文档中的解
Wesley13 Wesley13
3年前
JAVA NIO 直接缓冲区和非直接缓冲区
前面我们一直说NIO能够提高性能,那么到底如何提高效率。本篇就接着上一篇文章的缓冲区,来看看直接缓冲区和非直接缓冲区。非直接缓冲区首先看看非直接缓冲区。我们之前说过NIO通过通道连接磁盘文件与应用程序,通过缓冲区存取数据进行双向的数据传输。物理磁盘的存取是操作系统进行管理的,与物理磁盘的数据操作需要经过内核地址空间;而我们的Java应用