Netty学习之NIO---通道Channel(一)
一、关于通道的简单概述:
通道主要用于源节点和目标节点的连接,channel本身不存储数据,需要配合缓冲区进行数据的传输。
二、获取通道的主要途径:
1.Java针对支持通道的类提供了getChannel()方法;
2.在JDK1.7中的NIO.2,针对各个通道提供了静态方法open();
3.在JDK1.7中的NIO.2,的Files工具类中提供了newByteChannel()方法;
三、通过程序来学习一下通道的基本使用方法:
public class ChannelTest { //通道之间的数据传输 @Test public void test3() throws IOException { FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("4.jpg"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE); inChannel.transferTo(0,inChannel.size(),outChannel); // outChannel.transferFrom(inChannel,0,inChannel.size()); //两种方式一样 inChannel.close(); outChannel.close(); } //使用直接缓冲区完成文件的复制 @Test public void test2() throws IOException { FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); //内存映射文件 MappedByteBuffer inMapBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); MappedByteBuffer outMapBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size()); //直接对缓冲区进行数据的读写操作 byte[] dst = new byte[inMapBuffer.limit()]; inMapBuffer.get(dst); outMapBuffer.put(dst); inChannel.close(); outChannel.close(); } //使用通道完成文件的复制(非直接缓冲区) @Test public void test1(){ FileInputStream fis = null; FileOutputStream fos = null; // 1.获取通道; FileChannel inChannel = null; FileChannel outChannel = null; try { fis = new FileInputStream("1.jpg"); //文件路径 fos = new FileOutputStream("2.jpg");//将文件复制到的路径 inChannel = fis.getChannel(); outChannel = fos.getChannel(); } catch (FileNotFoundException e) { e.printStackTrace(); } // 2.分配指定到小的缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); try { while(inChannel.read(buffer)!=-1){ // 3.将通道中的数据存入缓冲区; buffer.flip(); outChannel.write(buffer); // 4.将缓冲区的数据写入通道中 buffer.clear(); } } catch (IOException e) { e.printStackTrace(); }finally { if(inChannel!=null){ try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if (outChannel!=null){ try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } }if(fis!=null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } }if(fos!=null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }最后这里对直接缓冲区和非直接缓冲区做个笔记:
直接缓冲区与非直接缓冲区的区别:
1.非直接缓冲区:将Buffer建立在JVM的内存中,数据传输较直接缓冲区慢,不太消耗内存;
2.直接缓冲区:将Buffer建立在物理内存中,数据传输快,但十分消耗机器的内存。