09 多点拷贝

1 使用多线程和文件流完成多点拷贝


import java.io.File;
import java.io.RandomAccessFile;

public class RandomAccessFileTest
{
	public static long totalSize = 0l;

	public static void main(String[] args) throws Exception
	{
		RandomAccessFileTest raft = new RandomAccessFileTest();
		raft.threadDownLoad("C:\\Users\\zhangli\\Desktop\\receiveFiles\\1.avi",
				"C:\\Users\\zhangli\\Downloads\\木乃伊4\\The.Mummy.2017.720p.WEB-DL.XviD.AC3-FGT.avi", 1);
	}

	/**
	 * 将oldPath分为threadSize个线程拷贝到newPath
	 * @param newPath
	 * @param oldPath
	 * @param threadSize
	 * @throws Exception
	 */
	public void threadDownLoad(String newPath, String oldPath, int threadSize)
			throws Exception
	{
		File file = new File(oldPath);
		// 要下载的总大小
		long dataLength = file.length();
		System.out.println(dataLength);
		// 线程数
		threadSize = threadSize == 0 ? 5 : threadSize;
		long blockSize = dataLength / threadSize;
		// 如果文件大小不能整除线程个数,则线程个数加1
		threadSize = dataLength % threadSize == 0 ? threadSize : threadSize + 1;
		System.out.println("分" + threadSize + "个线程开始下载");
		for (int i = 0; i < threadSize; i++)
		{
			//每个线程一个单独的输入输出流,这个是读老文件
			RandomAccessFile rafold = new RandomAccessFile(oldPath, "r");
			//这个事写新文件
			RandomAccessFile rafNew = new RandomAccessFile(newPath, "rw");
			//计算每个线程开始的位置
			long startSize = blockSize * i;
			//设置新文件的写指针
			rafNew.seek(startSize);
			if(i + 1 == threadSize)
			{
				//最后一次要特别注意读写的数据块大小
				blockSize = dataLength - blockSize * (threadSize - 1);
			}
			//启动线程
			Thread thread = new Thread(new DownLoad(startSize, blockSize,
					rafold, rafNew, i + 1));
			thread.start();
		}
	}
}

import java.io.RandomAccessFile;

/**
 * 对文件完成拷贝
 * @author zhangli
 *
 */
class DownLoad implements Runnable
{
	//声明源文件
	private RandomAccessFile accessFile;
	//声明目的文件
	private RandomAccessFile newAccessFile;
	//从哪开始拷贝文件
	private long startSize;
	//拷贝多少数据
	private long blockSize;
	//线程的名字
	private int threadName;

	/**
	 * 构造方法
	 * @param startSize 从哪开始拷贝
	 * @param blockSize 拷贝多大
	 * @param accessFile 源文件
	 * @param newAccessFile 目的文件
	 * @param threadName 线程名字
	 */
	public DownLoad(long startSize, long blockSize,
			RandomAccessFile accessFile, RandomAccessFile newAccessFile,
			int threadName)
	{
		this.accessFile = accessFile;
		this.startSize = startSize;
		this.blockSize = blockSize;
		this.threadName = threadName;
		this.newAccessFile = newAccessFile;
	}

	@Override
	public void run()
	{
		try
		{
			System.out.println("线程" + threadName + "开始下载.....");
			byte[] buffer = new byte[1024];
			int len = -1;
			
			//文件块对1024取商
			long size = blockSize / 1024;
			//如果文件大小对1024不能整除,则size+1
			size = blockSize % 1024 == 0 ? size : size + 1;
			//在源文件上置开始为
			accessFile.seek(startSize);
			for (int i = 0; i < size; i++)
			{
				//最后一次循环,注意最后一个数据块的大小,不一定是1024的整数倍
				if(i + 1 == size)
				{
					//计算最后一个数据块的大小
					int lastBlockSize = (int) (blockSize - 1024 * (size - 1));
					System.out.println(threadName + " " +accessFile.getFilePointer());
					len = accessFile.read(buffer, 0, lastBlockSize);
				}
				else
				{
					//从源文件读出数据到buffer
					len = accessFile.read(buffer);
				}
				//len为-1,则到达文件末尾
				if(len == -1)
				{
					break;
				}
				//把buffer数据写入到目的文件
				newAccessFile.write(buffer, 0, len);
			}
			newAccessFile.close();
			accessFile.close();
			System.out.println("线程" + threadName + "下载成功!");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值