java 线程模拟文件下载

<span style="font-family: Arial, Helvetica, sans-serif;">package demo2;</span>
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Test3 {
	public static void main(String[] args) {
		int fileLength = 0;
		// 创建文件对象
		File file = new File("D:\\脚踝终结者.mp4");

		if (file.exists()) {
			fileLength = (int) file.length();
		}
		// 拿到没个线程需要执行的长度
		int length = fileLength % 4 == 0 ? fileLength / 4 : fileLength / 4 + 1;
		// 如果取余4不等于0 每一个多读一个字节
		// 算一下最后一个需要读取的长度
		int lastLength = fileLength - (length * 3);
		// 启动线程
		DownLoad l1 = new DownLoad(0, length);
		DownLoad l2 = new DownLoad(length, length);
		DownLoad l3 = new DownLoad(length * 2, length);
		DownLoad l4 = new DownLoad(3 * length, lastLength);

		l1.start();
		l2.start();
		l3.start();
		l4.start();

	}
}

class DownLoad extends Thread {
	// 需要什么?
	// 需要确定开始的位置和读取的长度
	private int start;
	private int length;

	public DownLoad(int start, int length) {
		super();
		this.start = start;
		this.length = length;
	}

	public void run() {
		// 随机读写流
		// 注意一个随机读写流不能同时读和写,想要读和写,创建两个随机读写流对象
		RandomAccessFile read = null;
		RandomAccessFile write = null;
		try {
			System.out.println(Thread.currentThread().getName() + "开始复制");
			read = new RandomAccessFile("D:\\脚踝终结者.mp4", "rw");
			write = new RandomAccessFile("d:\\123.mp4", "rw");
			// 开始读写
			read.seek(start);
			write.seek(start);
			// 将start之前的内容跳过
			// 读取 创建数组的长度和读取数据的长度相同
			byte[] b = new byte[length];
			read.read(b);
			write.write(b);
			System.out.println(Thread.currentThread().getName() + "复制完成");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (read != null) {
				try {
					read.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (write != null) {
				try {
					write.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

用于文件大小较小的情况下。

read.seek(start);
			write.seek(start);
			byte b[] = new byte[1024];
			int len = 0;
			int i = 0;
			while(true){
				if(length -i<1024){
					read.read(b, 0, length-i);
					write.write(b,0,length-i);
					break;
				}
				else{                                 //length - i>1024 也就是当前读入的数据是比1024大,那么就先读一个1024的长度,然后把读
					len = read.read(b);          //的长度记录下来,接着读,如果还是length的长度减去已读的长度还是大于1024,那么就在读
					i=i+len;                   //个1024,然后记录所读的长度,接着读,如果用总长度减去已读过的长度,乳沟小于1024,则读此
					write.write(b, 0, len);  //长度,至此  此文件读取结束,结束循环,等着下一个文件进入。
				}
			}
用于文件过大的情况下。


步骤:获取文件的大小,每个线程平均分配文件的长度,最后一段数据做特殊考虑,创建随机读写流,对文件进行读写。创建线程,启动线程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值