【分享】使用FileChannel进行文件拷贝

前言: 项目实际编写中,使用到了多种文件拷贝方式,有包括专门使用c写了拷贝工具,供给Java调用,也有使用标准的输入输出流,这里分享的是借助 FileChannel 来读写,nio中传送数据使用channel+buffer,大的数据可以使用allocateDirect申请直接内存传输以提高效率。使用示例和注意事项如下:

核心代码如下:

public Boolean channelCopy(String sourcePath, String destPath) {
        Boolean result = false;
        FileChannel sourceChannel = null;
        FileChannel destChannel = null;
        try {
            sourceChannel = new RandomAccessFile(sourcePath, "r").getChannel(); // 使用RandomeAccessFile实际比InputStream略快,注意读写标识
            destChannel = new FileOutputStream(destPath).getChannel();
            long size = sourceChannel.size();
            for (long left = size; left > 0; ) {
                long transferSize = sourceChannel.transferTo((size - left), left, destChannel);
                left = left - transferSize;
            }
            result = true;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            result = false;
        } finally {
            try {
                if (sourceChannel != null) {
                    sourceChannel.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }

            try {
                if (destChannel != null) {
                    destChannel.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return result;
    }

注意点:

1. channel.transferTo((size - left), left, destChannel) 方法有一个2G(Integer.Max_VALUE 2147483647 )的限制,参照:

使用transferTo方法限制文件传输大小的原因分析_transforto_狗灬的博客-CSDN博客

 sun.nio.ch.FileChannelImpl#transferTo 中有个限制,也就是Integer.Max_VALUE()

2.  使用  RandomeAccess 而不是 FileInputStream,实测3.49G的文件在win11,32G,12代cpu上,使用FileInputStream ==》 4381ms完成,使用RandomAccessFile ==> 2390ms完成。有一定的效率差的,要注意读写环境的字符集要正确,避免中文乱码,且注意一下new RandomAccessFile(sourcePath, "r")的权限标识,尽量使用r,避免原始文件不存在会创建文件,或者提前判断。

其他参考: fileChannel全解
https://www.cnblogs.com/scooter8/p/12921327.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值