RandomAccessFile实现多线程文件复制

来源:互联网 发布:php 做数据统计图 编辑:程序博客网 时间:2024/06/05 14:38

RandomAccessFile

RandomAccessFile是Java体系中输入/输出流体系中功能最丰富的类之一,拥有强大的API,既支持文件的读,又支持文件的写;支持“随机访问”的方式,即程序可以直接跳转到文件的任意地方来读写数据。利用这个特性可以实现文件的多线程复制,将大文件分成若干段,每一段启动一个线程复制该段的文件,大大提高了效率。

代码实现

import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;class CopyFileThread extends Thread{    private RandomAccessFile in;    private RandomAccessFile out;    private long start;    private long end;    /**     *      * @param in 源文件地址     * @param out 目标文件地址     * @param start 分段复制的开始位置     * @param end  分段复制的结束位置     */    public CopyFileThread(String in, String out,            long start, long end){        this.start = start;        this.end = end;        try {            this.in = new RandomAccessFile(in, "rw");            this.out = new RandomAccessFile(out, "rw");        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }    public void run(){        try {            in.seek(start);            out.seek(start);            int hasRead = 0;            byte[] buff = new byte[1024*1024];            while(start<end && (hasRead = in.read(buff)) != -1){                start += hasRead;                out.write(buff, 0, hasRead);            }        } catch (IOException e) {            e.printStackTrace();        }finally{            try {                in.close();                out.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}public class ThreadsCopyFile {    /**     *      * @param sourcePath 源文件路径     * @param targetPath 目标文件路径     * @param ThreadNums 设定的线程数     * @throws IOException     */    public void startCopy(String sourcePath, String targetPath, int ThreadNums)            throws IOException{        long fileLength = new File(sourcePath).length();        //很有可能文件长度线程不能均分下载,预留一个线程复制最后剩余的部分        long segmentLength = fileLength/(ThreadNums-1);        int i;        for (i = 0; i < ThreadNums-1; i++) {            new CopyFileThread(sourcePath, targetPath, i*segmentLength, (i+1)*segmentLength).start();        }        new CopyFileThread(sourcePath, targetPath, i*segmentLength, fileLength).start();    }    public static void main(String[] args) throws IOException {    //demo中实现的是将e盘中这个目录下的电影复制到d盘下的tttt.rmvb        ThreadsCopyFile tcf = new ThreadsCopyFile();        String sourcePath = "E:\\NewFile\\AppData\\Xunlei\\[阳光电影www.ygdy8.com].金刚狼3:殊死一战.HD.720p.中英双字幕.rmvb";        String targetPath = "D:\\tttt.rmvb";        tcf.startCopy(sourcePath, targetPath, 3);    }}

总结

总之来说,如果线程越多,buffer区越大,耗费的内存资源也就越多,但是相对的能提升复制的效率。是一种以资源换取效率的方式,因此需要的线程数量的设置,需要考虑到资源的消耗。

原创粉丝点击