IT虾米网

Java多线程文件复制功能详解

leader 2021年07月26日 编程语言 213 0

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

发布评论
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java多窗口卖票问题详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。