多线程复制文件

MutiCopyFileUtil类

public class MutiCopyFileUtil {
    private String src;     // 源文件
    private String dst;     // 目标文件
    private int threadSize; // 开启的线程数

    public MutiCopyFileUtil(String src, String dst, int threadSize) {
        this.src = src;
        this.dst = dst;
        this.threadSize = threadSize;
    }

    // 拷贝文件的方法
    public void copyFile() {
        File file = new File(src);      // 源文件的File对象
        long fsize = file.length();     // 源文件的大小(字节数)
        // 每个线程要下载的文件块的大小(字节数)
        long block = (fsize % threadSize == 0) ? (fsize / threadSize) : (fsize / threadSize + 1);

        for (int threadId = 0; threadId < threadSize; threadId++) {
            // 开启多个线程进行文件的复制,每个线程复制一段区域
            new DownLoadThread(fsize, block, threadId).start();
        }
    }

    // 开启线程(内部类)
    private class DownLoadThread extends Thread {
        private long fsize;     // 文件大小
        private long block;     // 每个线程要下载的字节数大小
        private int threadId;   // 线程的ID号,从0开始
        private int bufferSize = 1024 * 1024;   // 缓冲区的大小(1M)

        public DownLoadThread(long fsize, long block, int threadId) {
            this.fsize = fsize;
            this.block = block;
            this.threadId = threadId;
        }

        @Override
        public void run() {
            try {
                // 以只读的方式读取源文件
                RandomAccessFile reader = new RandomAccessFile(src, "r");
                // 以读写的方法写入目标文件
                RandomAccessFile writer = new RandomAccessFile(dst, "rw");

                long startPosition = threadId * block;  // 每个线程复制的文件起始位置
                // 确定每个线程复制的文件结束位置
                long endPosition = startPosition + block > fsize ? fsize : startPosition + block;

                reader.seek(startPosition);     // 指定复制源文件的起始位置
                writer.seek(startPosition);     // 指定复制目标文件的起始位置
                byte[] buff = new byte[bufferSize];     // 设置一个缓冲区

                while (startPosition < endPosition) {   // 判断是否复制完成
                    // 读操作
                    int len = 0;    // 已经读取的实际长度
                    // 判断缓冲区是否读满
                    if (startPosition + bufferSize < endPosition) {
                        len = reader.read(buff);    // 读满缓冲区
                    } else {
                        // 把剩余的填不满缓冲区的数据写入的缓冲区
                        len = reader.read(buff, 0, (int) (endPosition - startPosition));
                    }
                    startPosition += len;       // 起始位置(每读一次就发生变化)

                    // 写操作
                    writer.write(buff, 0, len); // 把缓冲区中的数据写入指定文件的指定区域

                    // 输出提示信息
                    System.out.println("线程" + (threadId + 1) + "下载: " + len + "字节");
                }

                // 关闭资源
                reader.close();
                writer.close();
                System.out.println("线程" + (threadId + 1) + "下载完毕");

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

MutiCopyFileDemo类

public class MutiCopyFileDemo {

    public static void main(String[] args) {
        MutiCopyFileUtil copyFileUtil = new MutiCopyFileUtil("F:\\yinyue.mp3", "F:\\yinyue2.mp3", 3);

        // 开始复制
        copyFileUtil.copyFile();
    }
}

你可能感兴趣的:(多线程复制文件)