多个线程复制文件
最后会出现java虚拟机存储溢出错误,但不影响复制
/**
* 将一个500M的文件,用n个线程搬运到另外一个文件目录里去。
*
* @author Gin
*
*/
public class NJCopy extends Thread {
private File source;
private File targetDir;
private long off;
private int index = 0;
private int n;
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public NJCopy() {
super();
}
public NJCopy(File source, File targetDir, long off) {
super();
this.source = source;
this.targetDir = targetDir;
this.off = off;
}
public void run() {
try {
copy(source, targetDir, getOff(source));
} catch (IOException e) {
e.printStackTrace();
}
}
public synchronized long getOff(File source) {
System.out.println(Thread.currentThread().getName()+"获得第"+index+"段");
// if (index==4) {
// System.exit(0);
// }
System.out.println(n);
return (index++)*source.length()/n;
}
public void copy(File source, File targetDir, long off) throws IOException {
if (!targetDir.exists()) {
targetDir.mkdirs();
}
File target = new File(targetDir, source.getName());
// 获取源文件的随机访问文件流
RandomAccessFile raf_in = new RandomAccessFile(source, "r");
// 获取目标文件的随机访问文件流
RandomAccessFile raf_out = new RandomAccessFile(target, "rw");
int len = (int) (source.length()/n);
byte[] b = new byte[len*index];
if (len>b.length-off) {
len = (int) (b.length -off);
}
raf_in.seek(off);
raf_out.seek(off);
raf_in.read(b, (int) off, len);
// while ((len = raf_in.read(b)) != -1) {
raf_out.write(b, (int) off, len);
// }
raf_out.close();
raf_in.close();
}
public static void NJcopy(File source, File targetDir,int n) {
ArrayList<Thread> t = new ArrayList<>();
NJCopy njc = new NJCopy(source, targetDir, n);
njc.setN(n);
for (int i = 1; i <= n; i++) {
t.add(new Thread(njc,""+i));
}
for (Thread thread : t) {
thread.start();
}
}
public static void main(String[] args) {
File f= new File("C:\\Users\\Administrator\\Desktop\\udashi_fnt_1009900000X.exe");
File d= new File("C:\\Users\\Administrator\\Desktop\\1");
// NJCopy nj = new NJCopy();
//
// System.out.println(nj.getN()+"________________________");
NJcopy(f, d, 100);
}
}
//老师的
public class FileCopyByThread extends Thread{
private File source;
private File target;
private long start;
private long end;
public FileCopyByThread(File source, File target, long start, long end) {
super();
this.source = source;
this.target = target;
this.start = start;
this.end = end;
}
@Override
public void run() {
//统计本次拷贝的总长度
long size = 0;
RandomAccessFile raf_in = null;
RandomAccessFile raf_out = null;
try {
//获取源文件的输入流
raf_in = new RandomAccessFile(source,"r");
//获取目标文件的输出流
raf_out = new RandomAccessFile(target,"rw");
//跳过指定的字节数开始拷贝
raf_in.seek(start);
raf_out.seek(start);
byte[] b = new byte[1024];
int len = 0;
System.out.println(this.getName()+"开始拷贝");
while(((len = raf_in.read(b)) != -1) && (size <= end - start)){
//每次循环记录本次拷贝的真实长度
size += len;
//判断是否到了最后一段,并且长度不为end-start,将长度赋值为end-start
if (size>end-start) {
size = end-start;
len = (int) (size % 1024);
}
raf_out.write(b, 0, len);
}
System.out.println(this.getName()+"拷贝完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
File source = new File("C:\\Users\\Administrator\\Desktop\\udashi_fnt_1009900000X.exe");
File dir = new File("C:\\Users\\Administrator\\Desktop\\1");
File target = new File(dir,source.getName());
//获取每一段文件的长度
long item = source.length() / 4 + 1;
for(int i = 0;i < 4;i++){
new FileCopyByThread(source, target, i * item, (i + 1)*item).start();
}
}
}