多线程实现文件拷贝

关于多线程,大家可以看下这个博客

https://www.cnblogs.com/dolphin0520/p/3932921.html

真心不错。


下面直接贴我自己写的多线程实现文件拷贝的代码。


package util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DownLoadFile implements Runnable {
	
	public static int srcFileSize;  // 原文件大小 
	public static int threadNum = 5; // 线程数 
	public static ExecutorService executorService = Executors.newFixedThreadPool(threadNum);  
	private String url; //源文件路径
	private String dst; //目标文件路径
	private int start; //开始下载位置
	private int end; //结束下载位置
	
	
	public DownLoadFile() {
		super();
		// TODO Auto-generated constructor stub
	}


	public DownLoadFile(String url, String dst, int start, int end) {
		super();
		this.url = url;
		this.dst = dst;
		this.start = start;
		this.end = end;
	}


	/**
	 * 
	 * @param url 要拷贝的文件
	 * @param dst 拷贝到哪儿
	 * @return
	 * @throws IOException
	 */
	private void DownLoad(String url,String dst) throws IOException{
		//  获取原文件总大小  
        FileInputStream fileInputStream = new FileInputStream(url);  
        srcFileSize = fileInputStream.available();  
        fileInputStream.close();  
        
        // 获取每个线程需要复制的字节大小  
        int partSize = srcFileSize/threadNum;  
        
        // 目的文件夹如果不存在,则创建  
        File dstFile = new File(dst);  
        if(!dstFile.exists()){  
            dstFile.createNewFile();  
        }
        
        // 启用threadNum个线程进行复制文件  
        for(int i=0;i<threadNum;i++){  
            int start = partSize * i;  
            int end = (i==(threadNum-1))?srcFileSize:partSize*(i+1);  
            DownLoadFile dLF = new DownLoadFile(url, dst, start, end);  
            executorService.execute(dLF);  
        }  
        executorService.shutdown();
	}

	//执行拷贝
	public void run() {
		System.out.println("start:" + start + "  end:" + end );
		
		try {  
            String threadName = Thread.currentThread().getName(); // 线程名  
            System.out.println("线程"+threadName+"开始拷贝文件数据,拷贝数据段:"+start+"-"+end);  
              
            // 定位目标文件位置  
            RandomAccessFile randomAccessFile = new RandomAccessFile(dst, "rw");  
            randomAccessFile.seek(start);  
              
            // 定位原文件位置  
            InputStream inputStream = new FileInputStream(url);  
            inputStream = skipFully(inputStream,start);   
              
            // 复制文件内容  
            int sumSize = end - start; // 复制总字节数  
            int readSize = 1024*1024*8; // 缓存8MB  
            while(sumSize>0){  
                //  缓存大于拷贝字节,使用拷贝字节  
                if(readSize>sumSize){  
                    readSize = sumSize;  
                }  
                  
                // 从原文件输入流获取拷贝字节数据  
                byte[] tmp = new byte[readSize];  
                inputStream.read(tmp);  
                  
                // 向目标文件写入拷贝字节数据  
                randomAccessFile.write(tmp);  
                sumSize -= readSize;  
            }  
              
            // 拷贝完毕后,双方都关闭  
            inputStream.close();  
            randomAccessFile.close();  
             
            System.out.println("线程"+threadName+"拷贝数据结束,数据段:"+start+"-"+end);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
	}
	
	public static InputStream skipFully(InputStream in,long num)throws Exception{  
        long remainning = num;  
        long len = 0;  
        while(remainning>0){  
            len = in.skip(num);  
            remainning -= len;  
        }  
        return in;  
    }  
	
	
	public static void main(String args[]) {
		DownLoadFile d = new DownLoadFile();
		try {
			d.DownLoad("D:\\1.exe","D:\\\\1_copy.exe");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/sheng_xinjun/article/details/80582264