多个线程复制文件

最后会出现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();
        }
    }
}