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");
}
}