多线程断点下载的一个基础了解

多线程断点下载的一个基础了解

(初级-本地下载)

1.RandomAccessFile

1)简单介绍

是一种任意存取流、是处理流的一种,其对象包含一个记录指针能以任意访问的方式,程序可以跳到文件的任意位置进行读写。因而可以利用这个流,利用多线程来实现多断点下载,加快下载速度。

继承于java.lang.Object类,位于java.io包下。

2)构造器

创建实例时需要指定一个mode参数,用来指定访问模式。

本文主要用只读和读写两种模式

3)两个主要方法

-1:  long getFilePointer() 获取文件记录指针当前的位置

-2 : void seek(long pos) 将文件指针定位到指定pos位置

位置的单位都是B,即字节

-3 :使用实例:

用任意存取流的对象来调用

randomAccessFile.seek(100); // 将文件指针移动到第100个字节的位置。

2.文件记录指针

这对于本文实现多线程的断点下载很重要,条件基于这个指针指向而设置。

1)简单介绍

"文件记录指针" 通常指的是一个指向文件中某个位置的指针。这个指针可以用于定位文件中的数据,以便读取或写入特定的位置。文件记录指针的概念常常与随机访问文件相关。

2)文件指针的定位

文件指针指示了文件中当前读取或写入的位置。在顺序访问中,文件指针从文件的开头逐渐移动到文件的末尾。而在随机访问中,可以通过文件指针直接跳转到文件的任意位置。

不指定的情况下不会指向已经读写的位置(除了顺序写时,最终会指向文件末尾已经写完的最后一个字节)

3)初始位置

文件记录指针的起始位置为0是一种通用的约定,而不是一个绝对的规定。这约定在计算机科学中是一种普遍的惯例,多数编程语言和文件系统都遵循这个规定。

这种约定的历史起源可以追溯到低级别的硬件和操作系统设计。在很多系统中,文件被认为是一系列的字节或块,这些字节按照从0开始的索引进行编号。因此,将文件记录指针的初始位置设置为0是直观且方便的选择。

当你打开一个文件时,文件记录指针通常会被设置为文件的起始位置,即0。这使得文件指针的移动更容易理解,因为它与文件中的字节索引直接对应。

4)顺序读取的终止位置

指向文件的末尾。

例如图片有888888B则指针最终会指向位置888888B,是同样的。

3.run方法

1)成员变量设置

开始下载的位置和终止下载的位置

两个File对象,方便读写

注意,由于是继承于Tread类的方法,这些变量不是多线程共享的,每个线程都有自己的一套。

2)处理

最后一次要达到规定的线程下载结束位置时,通过处理用于传输的数组大小来使得正好传输到满足要求的数据:

if ((this.trunPosition < this.start + num + 1024 - 1)){
                    b = new byte[(int) (this.trunPosition - num - this.start + 1)];
                }

这使得该线程下载文件终止的位置能恰好在规定处,使得多个线程的下载能合在一起。而该线程的任意存取流对象的记录指针——>指向规定下载结束位置+1或文件末尾位置

if(raFin.getFilePointer() >= this.trunPosition){
                    //System.out.println(Thread.currentThread().getName()+" "+len);
                    //System.out.println(Thread.currentThread().getName()+" "+b.length);
                    //System.out.println(raFout.getFilePointer());
                    break;
                }

//采用继承于Thread类的重写run方法创建线程
class DownMuldo extends Thread {
	long start;
	long trunPosition;
	File filein = new File("E:\\BaiduNetdiskDownload\\wen\\query.avi");
	File fileout = new File("E:\\BaiduNetdiskDownload\\wen\\querydownload.avi");

	@Override
	public void run() {

		long allLength = filein.length();

		RandomAccessFile raFin = null;
		RandomAccessFile raFout = null;

		byte[] b = new byte[1024];
		int len = 0;
		long num = 0;
		try {
			raFin = new RandomAccessFile(filein, "r");
			raFout = new RandomAccessFile(fileout, "rw");		
			raFin.seek(start);
			raFout.seek(start);
			while (true) {
				if ((this.trunPosition < this.start + num + 1024 - 1)){
					b = new byte[(int) (this.trunPosition - num - this.start + 1)];
				}
				len = raFin.read(b);
				raFout.write(b,0,len);
				num += (long) len;
				System.out.println(Thread.currentThread().getName());
				if(raFin.getFilePointer() >= this.trunPosition){
					//System.out.println(Thread.currentThread().getName()+" "+len);
					//System.out.println(Thread.currentThread().getName()+" "+b.length);
					//System.out.println(raFout.getFilePointer());
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			
			try {
				if(raFin != null){
					raFin.close();
				}
				if(raFout != null){
					raFout.close();
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}

	}
}

4.创建线程

初始化专属于线程的一些变量,主要是对起始位置和终止位置的设置,本文采用4部分下载或者说复制。

public class MulRoute {
	static boolean flag = true;
	public static void main(String[] args) {

		DownMuldo m1 = new DownMuldo();
		DownMuldo m2 = new DownMuldo();
		DownMuldo m3 = new DownMuldo();
		DownMuldo m4 = new DownMuldo();

		m1.start = 0;
		m1.trunPosition = m1.filein.length() / 4 - 1;
		m1.setName("下载线程1");
		System.out.println(m1.start);

		m2.start = m1.trunPosition + 1;
		m2.trunPosition = m2.start + m1.filein.length() / 4 - 1 - 1;
		m2.setName("下载线程2");
		System.out.println(m2.start);

		m3.start = m2.trunPosition + 1;
		m3.trunPosition = m3.start + m1.filein.length() / 4 - 1 - 1;
	    m3.setName("下载线程3");
	    System.out.println(m3.start);

		m4.start = m3.trunPosition + 1;
		m4.trunPosition = m1.filein.length();
		m4.setName("下载线程4");
		System.out.println(m4.start);

		//m1.start();
		//m2.start();
		//m3.start();
		//m4.start();

	}
}

5.总结

1.本文通过仿真,了解多线程断点下载的很初级的方法和理念,能够成功复制/下载视频、文件、图片等。

2.通过使用,熟悉了文件记录指针。

3.后续有待扩展:通过文件记录指针记录终止下载的位置,用户发出重新下载指令后,从记录的位置开始重新下载。只要明白了随机存取的文件记录指针,这实际不难。

4.期待大家的批评指正,感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值