android上传视频 断点续传,Android断点续传原理及实现

这篇博客介绍了如何使用Java的HttpURLConnection和RandomAccessFile实现文件的断点续传下载功能。通过设置请求头的Range属性,可以指定下载文件的部分字节,再利用RandomAccessFile的seek方法在文件中指定位置写入数据,从而实现下载的暂停和续传。多线程下载则是将文件分成多个部分,每个线程负责下载一部分,并写入到文件的相应位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理:利用HttpURLConnection进行从网站上下载文件时,我们可以利用HttpURLConnection的setRequestProperty()方法,对我们要读取的字节部分进行控制,比如:1.Range=0-100代表只读取前100个字节。

2.Range=100-500代表读取从第100个字节开始,读到第500个字节为止。

3.Range=100-则代表从第100个字节开始读取,一直读取到文件末尾结束。

这样我们就可以轻松的实现对文件的各部分的读取了,我们只需要在暂停时记录一下已经读取到的位置,在重新开始的时候利用setRequestProperty()方法设置一下我们要读取的字节位置即可。

这里还有一个问题就是我们应该怎样将读取到的字节流写入文件中,由于File是不支持在指定处写入字节的,因此我们这里要使用RandomAccessFile来进行字节流的写入,RandomAccessFile有一个方法seek(long),允许我们指定要写入的位置。

这样两者结合,就能够轻易的实现文件的断点续传了。

多线程断点续传实现原理相同,只是利用多个线程同时下载,每个线程指定要下载的字节部分,写入到文件的指定部分。故这里只给出了单线程断点续传下载的实现部分:class SingleDownloadTask{

private String filePath;

private int contentLength;

private int readLength;

private RandomAccessFile file=null;

private boolean isPause=false;

private URL url;

public boolean isDownloading() {

return isDownloading;

}

private boolean isDownloading=false;

private Handler mHandler=new Handler();

public SingleDownloadTask(String urlStr,String filePath) {

this.filePath=filePath;

readLength=0;

contentLength=0;

try {

url=new URL(urlStr);

} catch (MalformedURLException e) {

e.printStackTrace();

}

}

//download from pos

public void download(){

new Thread(new Runnable() {

@Override

public void run() {

isDownloading=true;

HttpURLConnection conn=null;

InputStream is=null;

BufferedInputStream bis=null;

try {

file=new RandomAccessFile(filePath,"rw");

file.seek(readLength);

conn= (HttpURLConnection) url.openConnection();

if(readLength==0){

contentLength=conn.getContentLength();

}else{

conn.setRequestProperty("Range","bytes="+readLength+"-");

}

is=conn.getInputStream();

bis=new BufferedInputStream(is);

byte[] bytes=new byte[1024];

int len=0;

while (!isPause&&((len=bis.read(bytes,0,1024)))!=-1){

file.write(bytes,0,len);

readLength+=len;

mHandler.post(new Runnable() {

@Override

public void run() {

float rate=((float)readLength)/contentLength;

mProgressBar.setProgress((int) (100*rate));

mTextView.setText((int)(100*rate)+"%");

}

});

}

isDownloading=false;

if (readLength>=contentLength){

mHandler.post(new Runnable() {

@Override

public void run() {

Toast.makeText(MainActivity.this, "文件下载成功,保存在"+filePath

, Toast.LENGTH_SHORT).show();

mImageView.setImageBitmap(BitmapFactory.decodeFile(filePath));

}

});

}

file.close();

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally {

if (bis!=null){

try {

bis.close();

if (is!=null){

is.close();

}

if (conn!=null){

conn.disconnect();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}).start();

}

public void start(){

isPause=false;

download();

}

public void pause(){

isPause=true;

}

}

Demo:

AAffA0nNPuCLAAAAAElFTkSuQmCC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值