Java NIO 通道(Channel) 学习笔记
一、通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。
二、通道的主要实现类
java.nio.channels.Channel 接口:
|—FileChannel
|—SocketChannel
|—ServerSocketChannel
|—DatagramChannel
三、获取通道
Java 针对支持通道的类提供了 getChannel() 方法
本地 IO:
FileInputStream/FileOutputStream
RandomAccessFile
网络IO:
Socket
ServerSocket
DatagramSocket
在 JDK 1.7 中的 NIO.2 针对各个通道提供了静态方法 open()
在 JDK 1.7 中的 NIO.2 的 Files 工具类的 newByteChannel()
四、通道之间的数据传输
transferFrom()
transferTo()五、分散(Scatter)与聚集(Gather)
分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中六、字符集:Charset
编码:字符串 -> 字节数组
解码:字节数组 -> 字符串
Channel代码实例:利用通道完成文件的复制
1.非直接缓冲区
//利用通道完成文件的复制(非直接缓冲区)
@Test
public void testChannel(){
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
//1. 获取通道
FileChannel inChannel = null;
FileChannel outChannel = null;
try{
fis = new FileInputStream("G:/MP4/00.mp4");
fos = new FileOutputStream("G:/MP4/01.mp4");
inChannel = fis.getChannel();
outChannel = fos.getChannel();
//2. 分配指定大小的非直接缓冲区
ByteBuffer buff = ByteBuffer.allocate(1024);
//3. 将通道中的数据存入缓冲区中
while(inChannel.read(buff) != -1){
buff.flip(); //切换读取数据的模式
//4.将缓冲区中的数据写入通道中
outChannel.write(buff);
buff.clear(); //清空缓冲区
}
}catch(IOException e){
e.printStackTrace();
}finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inChannel != null){
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outChannel != null){
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start));
}
2.直接缓冲区
@Test
public void testFileChannel(){
long start = System.currentTimeMillis();
try {
FileChannel inChannel = FileChannel.open(Paths.get("G:/MP4/00.mp4"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("G:/MP4/04.mp4"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// start 1.第一种实现方式:使用直接缓冲区完成文件的复制(内存映射文件)
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);
// end 1.第一种实现方式:使用直接缓冲区完成文件的复制(内存映射文件)
// start 2.第二种实现方式:通道之间的数据传输(直接缓冲区) transferTo || transferFrom
inChannel.transferTo(0, inChannel.size(), outChannel);
// outChannel.transferFrom(inChannel, 0, inChannel.size());
// end 2.第二种实现方式:通道之间的数据传输(直接缓冲区) transferTo || transferFrom
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start));
} catch (IOException e) {
e.printStackTrace();
}
}
还没有评论,来说两句吧...