`
xgcai
  • 浏览: 8190 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类
最新评论

多线程复制文件

阅读更多

 

 

记录一下多线程文件复制工具类、以后有需要可以拿来用。

存在一些问题:

A.怎么根据文件大小确定最佳的线程数 B.文件读取 buffer 大小多少才适合???  

 

/**
 * 
 */
package com.demo.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

import org.junit.Test;

/**
 * @author rico
 * 多线程文件复制工具类
 */
public class MultiThreadFileCopy {
	
	public static void main(String[] args) {
		//junit 断点好像调试不了线程/??/、?
		new MultiThreadFileCopy().testCopyFile();
	}
	
	@Test
	public void testCopyFile() {
		
		//怎么根据文件大小确定最佳的线程数
		int blocks = 3;		
		
		//源文件和目标文件
		String filePath = "F:/demo.log";
		String outFilePath = "F:/demo-copy-multi.log";
		
		try {
			File file = new File(filePath);
			long fileSize = file.length();
			long blockSize = fileSize / blocks;				//每个线程操作的文件大小
			long lastBlockSize = fileSize % blockSize;		//文件大小不能整除线程数,文件剩余的数据会被添加到最后一个线程中操作
			
			System.out.println("###fileSize: " + fileSize);
			System.out.println("###blockSize: " + blockSize);
			System.out.println("###lastBlockSize: " + lastBlockSize);
			
			for(int i=0; i<blocks; i++) {
				if(i == blocks-1) {
					blockSize += lastBlockSize;
				}
				
				Runnable r = new CopyThread(filePath, outFilePath, i, blockSize, fileSize);
				new Thread(r).start();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
		}
	}
	
	public class CopyThread implements Runnable {
		String filePath;
		String outFilePath;
		
		int block;
		long blockSize;
		long fileSize;
		
		public CopyThread(String filePath, String outFilePath, int block, long blockSize, long fileSize) {
			this.filePath = filePath;
			this.outFilePath = outFilePath;
			this.block = block;
			this.blockSize = blockSize;
			this.fileSize = fileSize;
		}
		
		@Override
		public void run() {
			FileInputStream fis = null;
			RandomAccessFile raf = null;
			
			try {
				System.out.println("####block: " + block *blockSize);
				
				fis = new FileInputStream(new File(filePath));
				raf = new RandomAccessFile(new File(outFilePath), "rw");
				
				fis.skip(block * blockSize);
				raf.seek(block * blockSize);
				
				//buffer 大小多少才适合???
				byte[] bytes = new byte[1024 * 100];
				int len = fis.read(bytes);
				long totalBlockSize = len;
				
				while(len > -1) {
					if(totalBlockSize < blockSize) {
						raf.write(bytes, 0, len);
						len = fis.read(bytes);
					} else if(totalBlockSize == blockSize) {
						raf.write(bytes, 0, len);
						len = -1;
					} else {
						if(totalBlockSize-len < blockSize) {
							int leftBlockSize = (int) (len - (totalBlockSize-blockSize));
							raf.write(bytes, 0, leftBlockSize);
							len = -1;
						}
					}
					
					System.out.println("####totalBlockSize: " + totalBlockSize);
					System.out.println("####len: " + len);
					
					totalBlockSize += len;
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if(fis != null)
						fis.close();
					
					if(raf != null)
						raf.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics