java断点续传,断点下载RandomAccessFile使用示例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/carlos1992/article/details/50463805

前言:

因为公司项目需要,在做一个类似朋友圈的功能,想达到朋友圈那样快速的效果,朋友圈发说说的时候,是非常快的,快到图片好像根本没有上传就成功了。其实 ,大家都知道,图片上传是很花时间的……产品经理又觉得,在那个界面一直来一个progressbar让用户等待不好,于是,就使用了后台来实现图片上传,并且,是断点续传的,如果图片没有传完,下次打开,会继续传。然后,在朋友圈界面,显示这条说说的时候,使用的是本地图片。


这中间有很多细节,以后再写博客介绍,这里写一下,这个功能实现过程中,使用到的,读文件的一个类:RandomAccessFile

这个类有一个指针,可以让你从文件的某一个部分开始读,创建了它的对象以后,可以直接来读写,我还没有去看过源码,总之 ,操作非常得方便:可以用它来实现断点续传,断点下载,多线程同时下载等等。


要点:

其实,无论是断点续传,还是多线程下载,都是对文件的操作,譬如多线程下载:一共开五个线程,每个线程下载20%,那第一个线程就从0开始往文件里写,第二个线程就从20%开始写,以些类推,每个线程写自己那一部分……就这样,就可以实现。网上有很多这方面的介绍,其中有一个写得比较好:


http://blog.csdn.net/akon_vm/article/details/7429245


我在这里,说一下我的经验:我们实现断点续传,其实 ,是将文件分块了,就是一个大的文件,分成很多小文件。但其实 ,又不是真的,一个10Mb的文件分成10个1M的文件,那样,算上源文件,总的占20M的空间了。所以,我们只是记录我们传到哪一个地方了,使用使用这个类的指针,下次还是从这里开始读取文件的一块,然后,再把读到的byte[]编码上传。


	/**
	 * 读取指定字节的数据
	 * 
	 * @param offset
	 *            从哪个字节开始读取
	 * @param filePath
	 *            要读取的文件的路径
	 * @return 返回读取指定字节的字节数组
	 */
	public byte[] readFile(long offset, String filePath) {
		RandomAccessFile randomAccessFile = null;
		try {
			// 初使化这个文件
			randomAccessFile = new RandomAccessFile(filePath, "r");
			byte[] temByte = null;
			// 判断传入的指针是否比总文件长度还要长,只要小于文件长度,才是正常的
			if (offset < randomAccessFile.length()) {
				// 把指针移到要开始的字节位置
				randomAccessFile.seek(offset);
				// 这里是做一个判断,判断从这个位置开始读取,读取这个长度,是否已经超过了文件的长度,一般情况下,我们的块的
				// 长度是固定的,比如1M,而对于一个10.5M的文件,要分11包,当读最后一个包的时候,就会出现这种情况
				if (offset + UploadPhotoTaskDto.BLOCK_SIZE > randomAccessFile
						.length()) {
					// 如果已经超过了文件的长度,初使化字节数组的时候,就用文件长度减去指针的位置
					temByte = new byte[((int) (randomAccessFile.length() - offset))];
					// 这个方法 ,会读取字节长度的数据,然后把数据存储到字节数组
					randomAccessFile.read(temByte);
				} else {
					// 如果我们要读的一个块的长度,没有超过文件的长度,那就把字节数组初始化为块的长度
					temByte = new byte[(int) UploadPhotoTaskDto.BLOCK_SIZE];
					randomAccessFile.read(temByte);
				}

				return temByte;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (randomAccessFile != null) {
				try {
					// 关闭文件流
					randomAccessFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}


注释已经非常详细了。过几天,会把整个断点上传的代码分享出来,androd方面的。

展开阅读全文

没有更多推荐了,返回首页