基于java nio的channel实现高效率复制文件

基于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();
        }
    }

}

运行结果:
基于java nio的channel实现高效率复制文件

上一篇:92_Go基础_1_60 拷贝文件


下一篇:RH358学习笔记--8(配置Web服务器学习)