多线程复制文件

package DemoThingTset;

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


class LoadThread implements Runnable {
		
	String sourceFile;
	String targetFile;
	int threadNo;
	int threadNum;

	int bufferSize = 1024;
	long fileSize;
	
	public LoadThread(String sourceFile, String targetFile, int threadNo,
			int threadNum) {
		super();
		this.sourceFile = sourceFile;
		this.targetFile = targetFile;
		this.threadNo = threadNo;
		this.threadNum = threadNum;
	}
	public void run() {
		File file = new File(sourceFile);
		FileInputStream randin = null;//选用FileInputStream是因为其有skip方法,但其没有length方法
		RandomAccessFile randout = null;//选用RandomAccessFile是因为其有seek方法
		try {
			randin = new FileInputStream(file);
			long blockSize = file.length()/threadNum;
			long startPoint = blockSize*threadNo;
			
			byte[] buffer = new byte[bufferSize];

			randout = new RandomAccessFile(targetFile, "rw");
	
//			出于各种原因,在Android手机调用 skip 方法最终跳过的字节数可能更少一些,所以以此修正
//			 long at = startPoint;
//			 while(at > 0){
//				long amt = randin.skip(at);
//				if(amt == -1){
//					throw new RuntimeException();
//				}
//				at -= amt;
//			 }
//
//			randin.skip(at);  
//	        randout.seek(at);
	        
			randin.skip(startPoint);  
	        randout.seek(startPoint);
	        
	        int temp;
	        while ((temp=randin.read(buffer))>=0) {
				randout.write(buffer, 0, temp);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			try {
				randin.close();
				randout.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
		}
		
	}
}

public class DemoTest {
	public static void main(String args[]) throws IOException {
		String sourceFile="D:/Downloads/aliedit.exe";
		String targetFile="D:/Downloads/aliedit3.exe";
		int threadNo;
		int threadNum=3;
		
		for(threadNo=0;threadNo<=threadNum;threadNo++){
			new Thread(new LoadThread(sourceFile,targetFile,threadNo,threadNum)).start(); 

		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,使用多线程复制文件通常是为了提高性能,特别是当处理大文件时,可以同时读取源文件和写入目标文件,而不需要等待整个操作完成。这里是一个简单的示例,展示了如何使用`java.util.concurrent`包下的`TransferService`来实现线程安全的文件复制: ```java import java.io.*; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.concurrent.*; public class FileCopyingTask implements Callable<Integer> { private final Path sourcePath; private final Path destinationPath; public FileCopyingTask(Path sourcePath, Path destinationPath) { this.sourcePath = sourcePath; this.destinationPath = destinationPath; } @Override public Integer call() throws IOException { try (InputStream in = Files.newInputStream(sourcePath); OutputStream out = Files.newOutputStream(destinationPath)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } return bytesRead; // 返回复制的字节数,用于跟踪进度 } } public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { Path sourceFile = Paths.get("source.txt"); Path destFile = Paths.get("destination.txt"); ExecutorService executor = Executors.newFixedThreadPool(5); // 创建固定大小的线程池 Future<Integer>[] futures = new Future[executor.executeAll(Arrays.asList( new FileCopyingTask(sourceFile, destFile.resolveSibling("part1")), new FileCopyingTask(sourceFile, destFile.resolveSibling("part2")), // ... 其他部分,如果需要的话 ))]; for (Future<Integer> future : futures) { // 等待所有任务完成,并获取每个任务返回的字节数 System.out.println(future.get()); } executor.shutdown(); // 关闭线程池 } } ``` 在这个例子中,我们创建了一个固定大小的线程池,将文件复制任务分解成多个小的部分,每个部分由一个单独的线程执行。注意,由于IO操作本身通常是线程安全的,所以直接对输入流和输出流进行读写通常不需要额外同步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值