多线程下载文件
来源:互联网 发布:淘宝限时秒杀11元 编辑:程序博客网 时间:2024/05/29 10:49
最近看了下多线程下载文件,下载总结一下。
原理:
1.首先访问服务器端,获取到需要下载文件的总大小,并在本地创建同样大小的空白文件;这一步很简单,用你熟悉的任何一种网络访问方法,访问服务器都可以,请求成功后获取内容长度,之后利用RandomAccessFile这个类,创建空白文件,把内容长度设置为文件大小。
2.等分任务,计算出每个线程的开始下载位置以及结束下载位置;根据步骤1中获取到的文件长度,除上想要开启的线程总数,求得的整数为每个线程的下载任务大小blockSize,开始下载位置=i*blockSize(i从0开始),停止下载位置=(i+1)*blockSize-1.
3.开启多个线程,为每个线程设置开始下载的位置以及结束下载位置;这一步就开始请求服务器进行真正的文件下载了,需要注意的就是要设置网络请求时的开始位置和停止位置setRequestProperty("Range", "bytes="+startIndext+"-"+endIndext);,responsecode不是200而是206,之后还是利用RandomAccessFile类的seek方法设置文件写入的位置,write方法进行文件的写入。
代码:
package com.example.multhread;import android.app.Activity;import android.os.Environment;import android.util.Log;import android.widget.Toast;import java.io.File;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.List;/** * Created by pactera on 2017/2/4. */public class DownloadManager { private static final String path = "http://10.5.92.12:8080/loginProject/gg.exe"; private static final String TAG = "DownloadManager"; private static final int ThreadSize = 3; private Activity activity; private List<MyThread> threads; public DownloadManager(Activity activity) { this.activity = activity; threads = new ArrayList<MyThread>(); } public void StartDownload () { //1.在Android客户端首先创建一个和需要下载的文件相同大小的空白文件 long fileSize = getFileSize(); //2.开启3个线程去下载对应文件 if (fileSize > 0) { startMutileThread(fileSize); //3.如果所有线程都下载完毕,服务器的资源就下载完毕了 ifDownLoadSuccess(); } else { ToastOnScreen("服务器访问异常,请稍后再试"); } } private long getFileSize() { try { URL url = new URL(path); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setConnectTimeout(5000); int code = con.getResponseCode(); if (code == 200) { long size = con.getContentLength();//获取文件长度 Log.d(TAG,"文件大小为:"+size); File f = new File(Environment.getExternalStorageDirectory(),"gg.exe"); RandomAccessFile file = new RandomAccessFile(f,"rwd");//在本地创建文件 file.setLength(size);//将要下载的文件长度,赋给本地文件 file.close(); return size; } } catch (Exception e) { e.printStackTrace(); } return 0; } private void startMutileThread(long fileSize) { long size = fileSize/ThreadSize;//获取每个线程需要下载文件的长度 for (int i=0; i<ThreadSize; i++) { long startIndex = i*size;//计算每个线程开始下载文件的位置 long endIndex = (i+1)*size-1;//停止下载文件的位置 if (i==ThreadSize-1) {//如果是最后一个线程,则直接下载完剩余的文件 endIndex = fileSize-1; } MyThread thread = new MyThread(startIndex,endIndex);//开启线程 threads.add(thread); thread.start(); } } private class MyThread extends Thread { private long startIndex; private long endIndex; public MyThread(long startIndex, long endIndex) { this.startIndex = startIndex;//开始下载的位置 this.endIndex = endIndex;//停止下载的位置 Log.d(TAG,startIndex+"-"+endIndex+"部分文件开始下载!"); } @Override public void run() { super.run(); try { URL url = new URL(path); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("Range","bytes="+startIndex+"-"+endIndex);//设置请求头,设置开始下载位置和停止位置 con.setConnectTimeout(5000); int code = con.getResponseCode(); if (code == 206) {//分段下载的返回码是206不是200 InputStream is = con.getInputStream(); File f = new File(Environment.getExternalStorageDirectory(),"gg.exe"); RandomAccessFile file = new RandomAccessFile(f,"rw");//在本地创建文件 file.seek(startIndex); int len; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { file.write(buffer,0,len); } is.close(); file.close(); Log.d(TAG,startIndex+"-"+endIndex+"部分文件下载完毕!"); } } catch (Exception e) { e.printStackTrace(); } } } private void ifDownLoadSuccess() { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); int closeThread = 0; for (MyThread t:threads) { if (!t.isAlive()) { closeThread++; } } if (closeThread == ThreadSize) { ToastOnScreen("下载完成"); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } private void ToastOnScreen(final String s) { activity.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(activity, s, Toast.LENGTH_LONG).show(); } }); }}
0 0
- 多线程技术下载文件
- 多线程下载文件
- 文件的多线程下载
- 使用多线程下载文件
- Android 多线程文件下载
- 多线程文件下载
- 实现多线程下载文件
- QT:多线程下载文件
- Java多线程下载文件
- java多线程下载文件
- c# 多线程下载文件
- 多线程下载文件
- c# 多线程下载文件
- Java多线程下载文件
- 多线程断点下载文件
- Java多线程下载文件
- Java多线程下载文件
- 多线程下载文件
- 【设计模式】【一】设计六大原则
- 轻量级ORM框架——第一篇:Dapper快速学习
- 目录的库函数操作
- C++11 新特性: unordered_map 与 map 的对比
- pom.xml第一行一直报错
- 多线程下载文件
- 关于UGUI的一些小小的拓展,给以后自己Mark一下
- Cryptdb学习笔记(1)——简介
- 深谈require和import
- play framework 2.x中dist打包之后利用-Dhttp.port无法更改端口的
- 《文本域字数监控》
- 蓝桥-图3-深度优先遍历-地图最短路径
- Java开发必会的Linux命令
- 轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑