Java NIO 三大组件之 Channel

Wesley13
• 阅读 614

Java NIO 之 Channel

一、什么是Channel

Channel用于源节点(例如磁盘)与目的节点的连接,它可以进行读取,写入,映射和读/写文件等操作。

在Java NIO中负责缓冲区中数据的传输。Channel本省不存储数据,因此需要配合缓冲区进行传输。(个人理解其实就是相当于保存两通信地间的上写问和进行读写操作,相当于邮局)

二、通道的主要实现类

java.nio.channels.Channel接口:

  • FileChannel(本地)
  • SocketChannel(TCP)
  • ServerSocketChannel(TCP)
  • DatagramChannel(UDP)

三、获取通道的方式

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

四、通道之间的数据传输

  • transferFrom()

  • transferTo()

    @Test public void test3() throws IOException { FileChannel inChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ); FileChannel outchannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); inChannel.transferTo(0,inChannel.size(),outchannel); //outchannel.transferFrom(inChannel, 0,inChannel.size()); inChannel.close(); outchannel.close(); }

其他两种两种传输方式

  1. 使用直接缓冲区完成文件的复制(内存映射文件)

    //实验证明如果传大型文件内存会出现大量占用,如果GC不对内存进行回收,无法确定OS何时把数据写入磁盘 @Test public void test2() throws IOException { FileChannel inChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ); FileChannel outchannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); //内存映射文件 MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); MappedByteBuffer outMappedBuf = outchannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size()); //直接对缓存区进行数据的读写操作 byte[] dst = new byte[inMappedBuf.limit()]; inMappedBuf.get(dst); outMappedBuf.put(dst); }

  2. 利用通道完成文件的复制(非直接缓冲区)

    @Test public void test1(){ String path = this.getClass().getClassLoader().getResource("1.jpg").getPath(); FileInputStream fis = null; FileOutputStream fos = null; FileChannel fisChannel = null; FileChannel fosChannel = null; try { fis = new FileInputStream(path); fos = new FileOutputStream("src/main/resources/2.jpg"); //获取通道 fisChannel = fis.getChannel(); fosChannel = fos.getChannel(); //二、分配指定大小的缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //三、将通道中的数据存入缓冲区中 while(fisChannel.read(buf) != -1){ buf.flip(); //切换读取数据的模式 //四、将缓冲区的数据写入通道中 fosChannel.write(buf); buf.clear(); } } catch (IOException e) { e.printStackTrace(); }finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } try { fos.close(); } catch (IOException e) { e.printStackTrace(); } try { fis.close(); } catch (IOException e) { e.printStackTrace(); } try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } }

分散(Scatter)与聚集(Gather)

  • 分散读取(Scattering Reads): 将通道中的数据分散到多个缓冲区中
  • 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
JAVA NIO(一)
1NIO概述1.1NIO(newIO)是一个可以替代javaIOAPI的API,NIO提供了与标准IO不同的工作方式,标准IO是基于字节流和字符流进行操作的,而NIO是基于channel和Buffer进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写到通道中,方式如例图示,JAVANIO的几个核心组成部分是channels,Buf
Wesley13 Wesley13
2年前
Java NIO学习笔记
JavaNIO是什么JavaNIO(NewIO)是从Java1.4版本开始引入的一个新的IOAPI,可以替代标准的JavaIOAPI。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。JavaNIO与IO
Wesley13 Wesley13
2年前
JAVA NIO入门(一)
一、JAVANIO概念  JAVANIO是从JDK1.4就开始有的,之前只用过IO流,其实NIO和IO一样都是可以用来读取或者写入文件,只不过原来的IO是面向流进行操作的,而NIO是面向缓冲区进行操作二、通过一个小例子初步了解下NIO如何进行文件读写 !(https://oscimg.oschina.net/oscnet/
Wesley13 Wesley13
2年前
NIO阻塞与非阻塞IO
一、使用NIO完成网络通信的三个核心1、通道(Channel):负责连接java.nio.channels.Channel接口|–SelectableChannel|–SocketChannel|–ServerChannel|–DatagramChannel|–Pipe.SinkChannel|–Pipe
Wesley13 Wesley13
2年前
Java NIO之文件处理
程序要操作本地操作系统的一个文件,可以分为以下三个部分:对文件位置的操作对文件的操作对文件内容的操作其中,对文件内容的操作在JavaNIO之Channel中已经有了介绍,通过FileChannel可以读/写文件内容。本文不做重复介绍,详情参考我的另一篇文章:JavaNIO之Channel。1\.对文件位置
Wesley13 Wesley13
2年前
NIO通道(channel)原理与获取
一、通道(Channel):用于源节点与目标节点的连接。在javaNIO中负责缓冲区中数据的传输。Channel本身不存储数据,因此需要配合缓冲区进行传输。二、通道的主要实现类java.nio.channels.Channel接口:|–FileChannel|–SocketChannel|–ServerSocketCha
Stella981 Stella981
2年前
Netty之缓冲区ByteBuf解读(一)
!(https://oscimg.oschina.net/oscnet/up6de4d71f462d9846befe00ec6505125a928.JPEG)\Netty在数据传输过程中,会使用缓冲区设计来提高传输效率。虽然,Java在NIO编程中已提供ByteBuffer类进行使用,但是在使用过程中,其编码方式相对来说不太友好,也
Wesley13 Wesley13
2年前
Java NIO系列教程(五) 通道之间的数据传输
在JavaNIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel(译者注:channel中文常译作通道)传输到另外一个channel。transferFrom()FileChannel的transferFrom()方法可以将数据从源通道传输到FileChannel中(译者注:这个方法在JDK文档中的解
Wesley13 Wesley13
2年前
Java NIO编程学习总结
目录1、同步,异步,阻塞,非阻塞的理解2、什么是BIO、NIO、AIO3、javaNIO常用类和方法介绍3.1.缓冲区Buffer3.2.通道Channel3.2.1FileChannel3.2.2SocketChan
Wesley13 Wesley13
2年前
JAVA NIO 直接缓冲区和非直接缓冲区
前面我们一直说NIO能够提高性能,那么到底如何提高效率。本篇就接着上一篇文章的缓冲区,来看看直接缓冲区和非直接缓冲区。非直接缓冲区首先看看非直接缓冲区。我们之前说过NIO通过通道连接磁盘文件与应用程序,通过缓冲区存取数据进行双向的数据传输。物理磁盘的存取是操作系统进行管理的,与物理磁盘的数据操作需要经过内核地址空间;而我们的Java应用