Java多線程文件復制功能


Java多線程文件復制功能

這里講解一個利用Java里面的RandomAccessFile流來實現多線程文件的快速復制功能。

新建一個線程類:

class BpTransf extends Thread {
    private File srcFile = null;
    private File dstFile = null;
    private long posStart;
    private long posEnd;

    /** * 線程類的構造方法 * * @param srcFile * 源文件 * @param dstFile * 目標文件 * @param posStart * 復制起點位置 * @param posEnd * 復制終點位置 * @throws IOException */
    public BpTransf(File srcFile, File dstFile, long posStart, long posEnd) throws IOException {
        this.srcFile = srcFile;
        this.dstFile = dstFile;
        if (!dstFile.exists()) {
            dstFile.createNewFile();
        }
        this.posStart = posStart;
        this.posEnd = posEnd;
    }

    @Override
    public void run() {
        RandomAccessFile rafWrite = null;
        RandomAccessFile rafRead = null;
        try {
            rafWrite = new RandomAccessFile(dstFile, "rw");
            rafRead = new RandomAccessFile(srcFile, "r");
        } catch (FileNotFoundException e) {
            System.out.println("沒有找到文件!");
        }

        byte[] b = new byte[1024 * 8];// 定義存儲數據的字節數組
        int len = 0;
        try {
            rafWrite.seek(posStart);// 設置寫文件指針的起點
            rafRead.seek(posStart);// 設置讀文件指針的起點
            while ((len = rafRead.read(b)) != -1) {
                rafWrite.write(b, 0, len);
                // 如果文件指針比復制終點位置都大則說明此段復制完畢,可停止復制
                if (rafWrite.getFilePointer() >= posEnd) {
                    // 若復制完畢則提示該線程復制完畢
                    System.out.println(this.getName() + "讀取完畢!");
                    break;
                }
            }
            rafWrite.close();
            rafRead.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

利用上面的線程類來復制文件

/** * 多線程復制文件 * */
public class ThreadsBpTransf {

    public static void main(String[] args) throws IOException {
        long startTime=System.currentTimeMillis();
        File srcFile = new File("src.mp4");// 源文件
        File dstFile = new File("dst.mp4");// 目標文件
        long srcSize = srcFile.length();// 源文件長度
        int threadCount = 8;// 線程數量
        // 因為讀取源文件時的字節數組大小設置為1024*8所以這里將每個線程復制的長度設定為1024*8的整數倍
        long avg = (srcSize / threadCount) / (1024 * 8) * 1024 * 8;// 將平均值轉換為1024*8的倍數
        BpTransf[] bp = new BpTransf[threadCount];// 新建線程數組

        // 若源文件不存在則提示並返回
        if (!srcFile.exists()) {
            System.out.println("源文件不存在。");
            return;
        }
        for (int i = 0; i < threadCount; i++) {
            // 如果是最后一個線程則需要讀取末尾所有字節,不是最后一個線程則按照1024*8的倍數分配空間
            if (i == threadCount - 1) {
                bp[i] = new BpTransf(srcFile, dstFile, i * avg, srcSize);
            } else {
                bp[i] = new BpTransf(srcFile, dstFile, i * avg, (i + 1) * avg);
            }
            // 分配每個線程需要讀取字節的長度
            bp[i].start();// 啟動線程
        }

        for (BpTransf bpTransf : bp) {
            try {
                bpTransf.join();// 判斷線程是否復制完畢
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("程序運行完畢。");// 提示程序運行完畢
        // 輸出文件前后復制大小
        System.out.println("源文件大小" + srcFile.length() + "" + ",復制后的文件大小:" + dstFile.length());
        
        long time=System.currentTimeMillis()-startTime;
        System.out.println("復制用時"+time/1000+"s");
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM