基于java nio的channel实现高效率复制文件
关键:其中的transferFrom基于零拷贝技术
package com.netty.redis.zookeeper.netty.unit1;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.nio.channels.FileChannel;
/**
* @Description: 第一天练习
* 通过使用 Channel 通道,完成复制文件。
* 本环节的目标是掌握以下知识:Java NIO 中 ByteBuffer、Channel 两个重要组件的使用。
* 接着是升级实战的案例,使用文件 Channel 通道的 transferFrom 方法,完成高效率的文件复制。
* @ClassName: oneday
* @Author zhaomx
* @Version 1.0
* @Date 2021-07-12 16:12
*/
@Slf4j
public class oneday {
public static void main(String[] args) throws IOException {
File srcFile = new File("E:\\cnki\\zhaomx-study\\git\\netty\\jdk-master.zip");
File dstFile = new File("E:\\cnki\\zhaomx-study\\git\\netty\\jdk-master-copy.zip");
copyFileByNio(srcFile, dstFile);
File dstFileIo = new File("E:\\cnki\\zhaomx-study\\git\\netty\\jdk-master-copy1.zip");
copyFileByIo(srcFile, dstFileIo);
}
/**
* 基于nio的Channel连接管道复制,transferFrom方法,零拷贝技术,减少cpu与缓存的io次数
*
* @param srcFile
* @param dstFile
* @throws IOException
*/
public static void copyFileByNio(File srcFile, File dstFile) throws IOException {
long start = System.currentTimeMillis();
log.info("nio channel start time {}", start);
if (srcFile == null || !srcFile.exists()) {
return;
}
FileInputStream fileIns = null;
FileOutputStream fileOuts = null;
FileChannel source = null;
FileChannel destination = null;
try {
fileIns = new FileInputStream(srcFile);
fileOuts = new FileOutputStream(dstFile);
source = fileIns.getChannel();
destination = fileOuts.getChannel();
destination.transferFrom(source, 0, source.size());
long end = System.currentTimeMillis();
log.info("end time {}", end);
log.info("nio channel start-end time {}", end - start);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileIns != null)
fileIns.close();
if (fileOuts != null)
fileOuts.close();
if (source != null)
source.close();
if (destination != null)
destination.close();
}
}
/**
* 传统io基于流复制
* @param srcFile
* @param dstFile
*/
public static void copyFileByIo(File srcFile, File dstFile) {
long start = System.currentTimeMillis();
log.info("io write start time {}", start);
try {
InputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile));
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(dstFile));
byte[] bytes = new byte[1024];
int i;
// 读取到输入流数据,然后写入到输出流中去,实现复制
while ((i = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, i);
}
long end = System.currentTimeMillis();
log.info("end time {}", end);
log.info("io write start-end time {}", end - start);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果: