import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; public class Demo { //线程个数
public static int threadCount = 3; //线程下载完成的个数
public static int finishedCount = 3;
/**
* 多线程下载测试类
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception { //1、连接服务器,获取一个文件,获取文件的长度,在本地创建一个大小跟服务器文件一样大的临时文件
String path = "http://192.168.1.100:8080/test.avi";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code==200)
{ //服务器返回的数据长度 实际上就是文件的长度
int length = conn.getContentLength();
System.out.println("文件总长度:"+length); //在客服端创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");
//指定创建的这个文件的长度
raf.setLength(length);
raf.close(); //假设是3个线程去下载资源
//平均每一个线程下载的文件的大小
int blockSize = length / threadCount;
for(int threadId=1;threadId<=threadCount;threadId++)
{
//线程下载的开始位置
int startIndex = (threadId-1)*blockSize;
int endIndex = threadId*blockSize;
if(threadId==threadCount)
{
endIndex = length; }
System.out.println("线程:"+threadId+" 下载:---"+startIndex+"--->"+endIndex); //启动线程
new DownloadThread(threadId,startIndex,endIndex,path).start();
} }
else
{
System.out.println("服务器错误");
} } public static class DownloadThread extends Thread
{
private int threadId; //线程id
private int startIndex;
private int endIndex;
private String path; public DownloadThread(int threadId, int startIndex, int endIndex,
String path) {
super();
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
} public void run() {
try { //检查是否存在记录文件下载长度的文件,如果存在读取这个文件的数据 File tempFile = new File(threadId+".txt");
if(tempFile.exists() && tempFile.length() >0)
{
FileInputStream fis = new FileInputStream(tempFile);
byte[] temp = new byte[1024];
int leng = fis.read(temp);
String downloadLen = new String(temp,0,leng);
int downloadLenInt = Integer.parseInt(downloadLen);
startIndex = downloadLenInt;
fis.close();
} System.out.println("线程:"+threadId+"实际下载:---"+startIndex+"--->"+endIndex); URL url = new URL(path);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET"); //重要 : 请求服务器下载部分的文件指定文件的位置
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); //从服务器请求全部资源 200 ok 如果从服务器请求部分资源 206 ok
int code = conn.getResponseCode();
System.out.println("code:"+code); //已经设置了请求的位置 返回的事当前位置对应的文件的输入流
InputStream is = conn.getInputStream(); //在客服端创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");
//随机写文件的时候从哪个位置开始
raf.seek(startIndex); //定位文件 int len = 0;
byte[] buffer = new byte[1024];
int total = 0;
while((len=is.read(buffer))!=-1)
{
//记录已经下载完成的长度
RandomAccessFile recordFile = new RandomAccessFile(threadId+".txt","rwd");
raf.write(buffer,0,len);
//下载完成的长度
total += len;
recordFile.write((total+startIndex +"").getBytes());
recordFile.close(); } is.close();
raf.close(); System.out.println("线程:"+threadId+"下载完毕了。。。"); } catch (Exception e) {
e.printStackTrace();
}finally
{
//用于删除各个线程记录已经下载完成的长度的文件
finishedCount--;
//所有线程下载完成
if(finishedCount==0)
{ for(int i=1;i<=threadCount;i++)
{
//删除记录文件
File deleteFile = new File(i+".txt");
deleteFile.delete();
} } }
} } }

java 多线程断点下载功能的更多相关文章

  1. java多线程断点下载原理(代码实例演示)

    原文:http://www.open-open.com/lib/view/open1423214229232.html 其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载 ...

  2. Java多线程断点下载文件

    Java实现断点续传+多线程下载 如下代码所示,每一步都有注解 思路: 通过URL连接到服务器上要下载的文件,得到文件的大小: 算出每条线程下载的开始位置和结束位置,例如,有两条线程下载100Byte ...

  3. java 多线程断点下载demo

    源码链接 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java ...

  4. Java多线程断点下载

    public static class DownloadThread extends Thread{ private int threadId; private int startIndex; pri ...

  5. Java实现多线程断点下载(下载过程中可以暂停)

    线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...

  6. Android(java)学习笔记216:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1.新建一个Android工程: (1)其中我们先实现布局 ...

  7. Android(java)学习笔记159:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1. 新建一个Android工程: (1)其中我们先实现布 ...

  8. andoid 多线程断点下载

    本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多 ...

  9. iOS开发网络请求——大文件的多线程断点下载

    iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...

随机推荐

  1. spring学习总结(一)_Ioc基础(下)

    本篇文章继续上篇文章讲解Ioc基础,这篇文章主要介绍零配置实现ioc,现在相信大家项目中也基本都是没有了xml配置文件.废话不多说.一起学习 代码示例 BookDao.java package com ...

  2. 设计模式笔记:适配器模式(Adapter)

    1. 适配器模式简介 1.1 模式定义 适配器模式:通过一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器从结构上分为:类适配器和对象适配器.其 ...

  3. mysql 分页数据错乱

    最近在使用mysql 分页查询数据的时候发现返回的数据与预期的不一样,显示数据重复错乱. 在官方文档 有这样一句话 If multiple rows have identical values in ...

  4. Navicat的使用技巧

    1.快速查找表:选中一个数据库,然后在右侧会弹出如下的搜索框,搜索表名即可 2.快速清空表的内容:在窗口选中一张表,右键,选择“清空表”

  5. python3实现感知器,简单神经网络

    三个输入,四个输出,四组数据 对numpy和矩阵运算还不是太熟悉,可能写的复杂了点,矩阵数组来回转换 代码请查看码云 运行结果片段

  6. MT【237】阿基米德三角形的一些常见性质

    阿基米德三角形的常见性质:抛物线:$x^2=2py,AB$为抛物线的弦,$AQ,BQ$为切线,记$Q(x_0,y_0)$则$1)k_{QA}*k_{QB}=\dfrac{p}{2x_0}$$2)k_{ ...

  7. bzoj2142: 礼物

    2142: 礼物 Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会 ...

  8. java将一个javabean转化为另一个javabean

    公司的项目是用webservice来进行前后台对接,启动后台后需要刷服务才能在前台生成对应的代码,但是有一个很恶心的地方,它给每个service都生成了一个model,于是出现后台只有一个javabe ...

  9. 【Luogu1937】仓配置(贪心,线段树)

    [Luogu1937]仓配置 题面 直接找洛谷把... 题解 很明显的贪心吧 按照线段的右端点为第一关键字,左端点第二关键字排序 然后线段树维护区间最小就可以啦 #include<iostrea ...

  10. 洛谷 P2725 邮票 Stamps 解题报告

    P2725 邮票 Stamps 题目背景 给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K -- 表示信封上能够贴 K 张邮票.计算从 1 到 M 的最大连续可贴出的邮资. 题目描 ...