如何快速使用NIO复制文件

使用NIO复制文件

利用NIO中的Channel(通道)这一特性实现对文件快速复制
情况一:如果文件大小在2GB以下
这个时候可以使用MappedByteBuffer直接把文件映射到内存中,在内存中实现复制,然后再映射到目的地,这样就可以将硬盘的读写转移到了内存中的读写,提高读写效率

public static void main(String[] args) throws Exception{
        //java.io.RandomAccessFile类,可以设置读、写模式的IO流类。
        //"r"表示:只读--输入流,只读就可以。
        RandomAccessFile randomAccessFile1 = new RandomAccessFile("被复制的文件的路径","r");
        //"rw"表示:读、写--输出流,需要读、写。
        RandomAccessFile randomAccessFile2 = new RandomAccessFile("复制后的文件要存储的路劲","rw");

        // 获得FileChannel管道对象
        FileChannel fileChannel1 = randomAccessFile1.getChannel();
        FileChannel fileChannel2 = randomAccessFile2.getChannel();

        // 获取文件的大小
        long size = fileChannel1.size();

        // 直接把硬盘中的文件映射到内存中
        MappedByteBuffer mappedByteBuffer1 = fileChannel1.map(FileChannel.MapMode.READ_ONLY, 0, size);
        MappedByteBuffer mappedByteBuffer2 = fileChannel2.map(FileChannel.MapMode.READ_WRITE, 0, size);

        // 循环读取数据
        for (long i = 0; i < size; i++) {
            // 读取字节
            byte byt = mappedByteBuffer1.get();
            // 保存到第二个数组中
            mappedByteBuffer2.put(byt);
        }
        // 释放资源
        fileChannel2.close();
        fileChannel1.close();
        randomAccessFile2.close();
        randomAccessFile1.close();
    }

情况二:要复制的文件大小超过2GB
这种情况,MappedByteBuffer不能直接将文件映射到内存,所以就需要进行分块操作,将大文件分为几次进行映射

public static void main(String[] args) throws Exception {
        /*
            使用MappedByteBuffer复制超过2GB的文件
         */
        // 创建RandomAccessFile对象
        RandomAccessFile randomAccessFile1 = new RandomAccessFile("day14\\aaa\\123.jpg", "r");
        RandomAccessFile randomAccessFile2 = new RandomAccessFile("day14\\bbb\\123Copy.jpg", "rw");

        // 创建管道对象
        FileChannel fileChannel1 = randomAccessFile1.getChannel();
        FileChannel fileChannel2 = randomAccessFile2.getChannel();

        // 如果文件大小超过2GB,则需要分块拷贝
        // 获取文件的总大小
        long size = fileChannel1.size();
        // 定义每次文件要拷贝的大小
        long everySize = 1024 * 1024 * 512;
        // 获取需要循环的次数
        long count = size % everySize == 0 ? size / everySize : size / everySize + 1;

        for (long i = 0; i < count; i++) {
            // 定义每次开始的位置
            long startSize = i * everySize;
            // 定义每次要拷贝的大小
            long trueSize = size - startSize >= everySize ? everySize : size - startSize;
            // 创建映射缓冲数组
            MappedByteBuffer map1 = fileChannel1.map(FileChannel.MapMode.READ_ONLY, startSize, trueSize);
            MappedByteBuffer map2 = fileChannel2.map(FileChannel.MapMode.READ_WRITE, startSize, trueSize);
            // 循环读取数据
            for (long j = 0; j < trueSize; j++) {
                // 读数据
                byte b = map1.get();
                // 写数据
                map2.put(b);
            }

        }
        // 关闭流,释放资源
        fileChannel2.close();
        fileChannel1.close();
        randomAccessFile2.close();
        randomAccessFile1.close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值