randomaccessfile 并发复制小文件和大文件 多线程

package com.myh.kb13.t805.homework;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @Description: 块的复写
 * @author:myh
 * @date: 2021/8/6  8:43
 */
public class CopyFile implements Runnable{
    private String source;
    private String target;
    private long readlen;
    //偏移量
    private long seek;

    public CopyFile(String source, String target, long readlen, long seek) {
        this.source = source;
        this.target = target;
        this.readlen = readlen;
        this.seek = seek;
    }

    @Override
    public void run() {
        //设置缓冲区 每个块中一次读1024个字节
        byte[] buffer=new byte[1024];

        try {
            RandomAccessFile in=new RandomAccessFile(source, "rw");
            RandomAccessFile out=new RandomAccessFile(target, "rw");
            in.seek(seek);
            out.seek(seek);

            //计算要读多少次
            //long是长整型

            long readCount = readlen<1024?1:readlen/1024;
            for (int i = 0; i < readCount; i++) {
                //如果最后一次 有剩余的一起读写
                if (i!= readCount-1) {
                    in.read(buffer);
                    out.write(buffer);
                }else {
                    //计算最后一块 建造一个临时的数组
                    long tempLen = readlen<1024?readlen:1024+readlen%1024;
                    byte[] temp=new byte[(int)tempLen];
                    in.read(temp);
                    out.write(temp);

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
package com.myh.kb13.t805.homework;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @Description:
 * @author:myh
 * @date: 2021/8/6  8:43
 */
//随机读写类  制造文件读取块  并根据块生成对应线程
public class CopyFileByRand {
    //定义块大小
    //最好根据硬盘的吞吐量来定义比较好 一般是100M  32M 64M  这个已经很像hadoop的源码了!!

    private final long BLOCK=1024*1024*16;//相当于每一个格子是16MB  单位是字节
    public void currentCopyFile(String sourceFile,String targetFile) {
        try {
            // 先把文件的分块
            RandomAccessFile in=new RandomAccessFile(sourceFile, "rw");
            RandomAccessFile out=new RandomAccessFile(sourceFile, "rw");
            //计算文件总长度
            long len=in.length();
            //计算有多少块(整除  要小心 可能会少一块 所以等一下最后一块一定要把长度=BOLCK+len%BLOCK)
            //防止文件特别小
            long block_size=len<BLOCK?1:len/BLOCK;
            //循环建造线程
            for (int i = 0; i < block_size; i++) {
                //设置写入文件的长度(占空格位置)
                out.setLength(len);
                //每次循环时设置源文件和目标文件的偏离seek
//                in.seek(i*BLOCK);
//                out.seek(i*BLOCK);

                //如果是最后一个 一定要加上剩余的长度
                if (i==block_size-1) {
                    //计算下最后一块的大小
                    long finalBlockSize=len<BLOCK?len:BLOCK+len%BLOCK;
                    new Thread(new CopyFile(sourceFile, targetFile, finalBlockSize, i*BLOCK)).start();

                }else {
                    new Thread(new CopyFile(sourceFile, targetFile, BLOCK, i*BLOCK)).start();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        CopyFileByRand cfb=new CopyFileByRand();
        cfb.currentCopyFile("d:/a.txt", "d:/a1.txt");
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值