Java NIO文件复制

基于FileChannel复制文件。

普通的NIO复制

    @Test
    public void testCopyFile() throws IOException {
        nioCopyFile("D:\\spark-2.2.3-bin-hadoop2.7.tgz", "D:\\spark-2.2.3-bin-hadoop2.7.tgz.copy");
    }

    /**
     * @author jimo
     */
    private void nioCopyFile(String srcPath, String destPath) throws IOException {
        final File srcFile = new File(srcPath);
        final File destFile = new File(destPath);

        if (!destFile.exists()) {
            destFile.createNewFile();
        }
        int buffSize = 16384;
        System.out.println("开始复制, buffer size=" + buffSize);
        long start = System.currentTimeMillis();
        try (FileInputStream fis = new FileInputStream(srcFile);
             FileOutputStream fos = new FileOutputStream(destFile);
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {

            int length;
            final ByteBuffer buff = ByteBuffer.allocate(buffSize);

            while ((length = inChannel.read(buff)) != -1) {
                // System.out.println("读取的字节数:" + length);
                // 翻转模式,读完该写了
                buff.flip();
                int outLen;
                while ((outLen = outChannel.write(buff)) != 0) {
                    // System.out.println("写入的字节数:" + outLen);
                }
                // 清空buff
                buff.clear();
            }
            // 强制刷新到磁盘
            outChannel.force(true);
        }
        final long end = System.currentTimeMillis();
        System.out.println(String.format("文件大小:%d MB,共花费:%d ms", srcFile.length() / 1024 / 1024, (end - start)));
    }

测试:

开始复制, buffer size=1024
文件大小:194 MB,共花费:3153 ms

开始复制, buffer size=8192
文件大小:194 MB,共花费:2225 ms

开始复制, buffer size=16384
文件大小:194 MB,共花费:2149 ms

理论上更快的方法

    /**
     * @author jimo
     */
    private void copyFileFast(String srcPath, String destPath) throws IOException {
        final File srcFile = new File(srcPath);
        final File destFile = new File(destPath);

        if (!destFile.exists()) {
            destFile.createNewFile();
        }
        int buffSize = 1024;
        System.out.println("开始复制, buffer size=" + buffSize);
        long start = System.currentTimeMillis();
        try (FileInputStream fis = new FileInputStream(srcFile);
             FileOutputStream fos = new FileOutputStream(destFile);
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {

            long size = inChannel.size();
            long pos = 0;
            // 最大传输的字节数
            long cnt;
            while (pos < size) {
                // 每次复制buffSize的数据
                cnt = size - pos > buffSize ? buffSize : size - pos;
                pos += outChannel.transferFrom(inChannel, pos, cnt);
            }
            // 强制刷新到磁盘
            outChannel.force(true);
        }
        final long end = System.currentTimeMillis();
        System.out.println(String.format("文件大小:%d MB,共花费:%d ms", srcFile.length() / 1024 / 1024, (end - start)));
    }

测试:实际上更差

开始复制, buffer size=16384
文件大小:194 MB,共花费:2400 ms

开始复制, buffer size=8192
文件大小:194 MB,共花费:2993 ms

开始复制, buffer size=1024
文件大小:194 MB,共花费:7475 ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值