NIO之通道(Channel)的原理与获取以及数据传输与内存映射文件详解编程语言
2023-06-13 09:20:45 时间
通道(Channel)
内存和IO接口之间加了 DMA(直接存储器),DMA向CPU申请权限,IO的操作全部由DMA管理。CPU不要干预。
早一代IO操作是由CPU负责IO接口
由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Channel只能与Buffer进行交互。通道主要用于传输数据,从缓冲区的一侧传到另一侧的实体(如文件、套接字 ),反之亦然;通道是访问IO服务的导管,通过通道,我们可以以最小的开销来访问操作系统的I/O服务;顺便说下,缓冲区是通道内部发送数据和接收数据的端点。
在标准的IO当中,都是基于字节流/字符流进行操作的,而在NIO中则是是基于Channel和Buffer进行操作,其中的Channel的虽然模拟了流的概念,实则大不相同。
内存和IO接口之间加了 DMA(直接存储器),DMA向CPU申请权限,IO的操作全部由DMA管理。CPU不要干预。
早一代IO操作是由CPU负责IO接口
1 package com.expgiga.NIO; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.nio.ByteBuffer; 7 import java.nio.MappedByteBuffer; 8 import java.nio.channels.FileChannel; 9 import java.nio.file.Paths; 10 import java.nio.file.StandardOpenOption; 12 /** 13 * 一、Channel:用于源节点与目标节点之间的连接。在Java NIO中,负责缓冲区中数据传输,Channel本身不存储数据,因此需要配合缓冲区进行传输。 14 * 15 * 二、Channel的实现类: 16 * java.nio.channels.Channel 接口: 17 * |-- FileChannel 18 * |-- SocketChannel 19 * |-- ServerSocketChannel 20 * |-- DatagramChannel 21 * 22 * 三、获取通道Channel 23 * 1.Java针对支持通道的类提供了getChannel()方法 24 * 本地IO 25 * FileInputStream/FileOutputStream 26 * RandomAccessFile 27 * 28 * 网络IO: 29 * Socket 30 * ServerSocket 31 * DatagramSocket 32 * 33 * 2.在jdk1.7中的NIO.2针对各个通道提供了静态方法open() 34 * 35 * 3.在jdk1.7中的NIO.2的Files工具类的newByteChannel() 36 * 37 * 四、通道之间的数据传输 38 * transferFrom() 39 * transferTo() 40 * 41 */ 42 public class TestChannel { 44 public static void main(String[] args) throws IOException { 46 /* 47 * 1.利用通道完成文件的复制(非直接缓冲区) 48 */ 49 FileInputStream fis = null; 50 FileOutputStream fos = null; 52 FileChannel inChannel = null; 53 FileChannel outChannel = null; 55 try { 56 fis = new FileInputStream("1.jpg"); 57 fos = new FileOutputStream("2.jpg"); 58 //1.获取通道 59 inChannel = fis.getChannel(); 60 outChannel = fos.getChannel(); 62 //2.分配指定大小的缓冲区 63 ByteBuffer buffer = ByteBuffer.allocate(1024); 65 //3.将通道中的数据缓冲区中 66 while (inChannel.read(buffer) != -1) { 68 buffer.flip();//切换成都数据模式 70 //4.将缓冲区中的数据写入通道中 71 outChannel.write(buffer); 72 buffer.clear();//清空缓冲区 73 } 74 } catch (Exception e) { 75 e.printStackTrace(); 76 } finally { 77 if (outChannel != null) { 78 try { 79 outChannel.close(); 80 } catch (IOException e) { 81 e.printStackTrace(); 82 } 83 } 85 if (inChannel != null) { 86 try { 87 inChannel.close(); 88 } catch (IOException e) { 89 e.printStackTrace(); 90 } 91 } 93 if (fis != null) { 94 try { 95 fis.close(); 96 } catch (IOException e) { 97 e.printStackTrace(); 98 } 99 } 101 if (fos != null) { 102 try { 103 fos.close(); 104 } catch (IOException e) { 105 e.printStackTrace(); 106 } 107 } 108 } 111 /* 112 * 2.利用(直接缓冲区)通道完成文件的复制(内存映射文件的方式) 113 */ 115 long start = System.currentTimeMillis(); 116 FileChannel inChannel2 = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ); 117 FileChannel outChannel2 = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); 119 //内存映射文件 120 MappedByteBuffer inMappedBuf = inChannel2.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); 121 MappedByteBuffer outMappedBuf = outChannel2.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size()); 123 //直接对缓冲区进行数据读写操作 124 byte[] dst = new byte[inMappedBuf.limit()]; 125 inMappedBuf.get(dst); 126 outMappedBuf.put(dst); 128 inChannel2.close(); 129 outChannel2.close(); 131 long end = System.currentTimeMillis(); 132 System.out.println("耗费的时间为:" + (end - start)); 134 /* 135 * 通道之间的数据传输(直接缓冲区) 136 */ 137 FileChannel inChannel3 = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ); 138 FileChannel outChannel3 = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); 140 inChannel3.transferTo(0, inChannel3.size(), outChannel3); 141 //等价于 142 // outChannel3.transferFrom(inChannel3, 0, inChannel3.size()); 144 inChannel3.close(); 145 outChannel3.close(); 146 } 147 }
15744.html
cjavamac相关文章
- mysql 导入 csv 大文件怎么打开_mysql导入超大内存的csv文件
- java安全之结合CC链注入无文件Tomcat内存马
- C++ 新特性学习(八) — 原子操作和多线程库[多工内存模型]
- JVM 一张图带你了解内存分配过程 搞懂逃逸分析|标量替换|指针碰撞|空闲列表|TLAB
- 【Rust 日报】2023-1-25 内存安全会议报告
- 【Android 热修复】热修复原理 ( 加载 Dex 文件到内存中 | DexClassLoader | PathClassLoader | 反射 Element[] dexElements )
- SQLServer 错误 17067 SQL Server断言:文件: <%s>,行 = %d %s。 此错误可能与时间有关。 如果重新运行该语句后错误仍然存在,请使用 DBCC CHECKDB 来检查数据库的结构是否完整,或重新启动服务器以确保内存中的数据结构未破坏。 故障 处理 修复 支持远程
- java 读取文件——按照行取出(使用BufferedReader和一次将数据保存到内存两种实现方式)详解编程语言
- [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义详解编程语言
- 掌握Linux服务器:查看内存使用情况(查看linux服务器内存)
- Linux内存映射文件:提高性能的利器(linux内存映射文件)
- Linux创建内存文件:极致性能拥抱(linux创建内存文件)
- 管理Linux文件系统与内存管理(linux文件内存)
- 内存最佳Linux虚拟机内存设置(linux虚拟机多大)
- Linux中的mmap函数:内存映射文件技术(mmaplinux)
- 解析Linux swap文件:优化内存管理和提升系统性能(linuxswap文件)
- 如何在 Redis 中设置最大内存限制(redis设置最大内存)
- 死扩大内存Redis 性能瓶颈警示(扩大内存导致redis卡)
- VCRedis x32解决32位系统服务器内存问题(vc-redis x32)
- Redis创新的高性能内存数据库(redis英语什么意思)
- PHP中文件缓存转内存缓存的方法
- C++内存泄漏及检测工具详解