该资源来源于李刚老师的疯狂JAVA讲义

InutStream openStream():打开与此URL链接,并返回一个用于读取该URL资源的InputStream.

提供的openStream()可以读取该URL资源的InputStream,通过该 方法可以非常方便的读取远程资源--甚至实现多线程下载。程序如下:

package com.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection; /**
* 多线程下载
* @author yulei
*
*/ //定义下载从start到end 的内容的线程
class DownThread extends Thread{
//定义字节数组(取水的竹筒)的长度
private final int BUF_LEN=32;
//定义下载的起始点
private long start;
//定义下载的结束点
private long end;
//下载资源对应的输入流
private InputStream is;
//将下载的字节输出到raf中
private RandomAccessFile raf;
//构造器,传入输入流,输出流和下载起始点、结束点
public DownThread(long start,long end ,InputStream is ,RandomAccessFile raf){
//输出改线程负责下载的字节位置
System.out.println(start+"---->"+end);
this.start=start;
this.end=end;
this.is=is;
this.raf=raf;
} public void run(){
try {
is.skip(start);
raf.seek(start);
//定义读取输入流内容的缓存数组
byte[] buff=new byte[BUF_LEN];
//本线程负责下载资源的大小
long contentLen=end-start;
//定义最多需要读取几次就可以完成本线程的下载
long times=contentLen/BUF_LEN+4;
//实际读取的字节数
int hasRead=0;
for (int i=0;i<times;i++){
hasRead=is.read(buff);
//如果读取的字节数小于0,则退出循环!
if(hasRead<0){
break;
}
raf.write(buff, 0, hasRead);
}
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭当前线程的输入流、输出流
finally {
try {
if(is!=null){
is.close();
}
if(raf!=null){
raf.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
} public class MutilDown {
public static void main(String[] args) { final int DOWN_TREAD_NUM=4;
final String OUT_FILE_NAME="down.jpg";
InputStream[] isArr=new InputStream[DOWN_TREAD_NUM];
RandomAccessFile[] outArr=new RandomAccessFile[DOWN_TREAD_NUM];
try {
//创建一个URL对象
URL url=new URL("http://www.baidu.com/img/bd_logo1.png");
//以此URL对象打开一个输入流
isArr[0]=url.openStream();
long fileLen=getFileLength(url);
System.out.println("网路资源的大小:"+fileLen);
//以输出文件名创建第一个RandomAccessFile输出流
outArr[0]=new RandomAccessFile(OUT_FILE_NAME, "rw");
//创建一个与下载资源相同大小的空文件
for (int i=0;i<fileLen;i++){
outArr[0].write(0);
}
//每线程应该下载的字节数
long numPerThread=fileLen/DOWN_TREAD_NUM;
//整个下载资源整除后剩下的余数
long left=fileLen%DOWN_TREAD_NUM;
for(int i=0;i<DOWN_TREAD_NUM;i++){
//为每个线程打开一个输入流、一个RandomAccessFile对象
//让每个线程分别负责下载资源的不同部分
if(i!=0){ //上面已经初始化一次了,所以这里写i!=0 即可
//以URL打开多个输入流
isArr[i]=url.openStream();
//以指定输出文件创建多个RandomAccessFile对象
outArr[i]=new RandomAccessFile(OUT_FILE_NAME,"rw");
} //分别启动多个线程下载网路资源
if(i==DOWN_TREAD_NUM-1){
//最后一个线程下载指定numPerThread+left个字节
new DownThread(i*numPerThread, (i+1)*numPerThread, isArr[i], outArr[i]).start();
}else{
//每个线程负责下载一定的numPerThread个字节
new DownThread(i*numPerThread,(i+1)*numPerThread,isArr[i], outArr[i]).start();
} } } catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} //定义获取指定网路资源长度的方法 public static long getFileLength(URL url) throws IOException{
long lenth=0;
//打开该URL对应的URLConnection
URLConnection con=url.openConnection();
//获取连接URL资源的长度
long size =con.getContentLength();
System.out.println("网路资源SIZE 的长度:"+size);
lenth=size;
return lenth;
} }

上面程序定义了DownTread线程类,该线程从InputStream中读取从start开始,到end结束的所有字节数据,并写入RandomAccessFile对象。这个DownThread线程类的run就是一个简单的输入、输出实现。

程序中MutilDown类中的main方法负责按如下步骤来实现多线程下载:

1 、创建URL对象。

2、获取指定URL对象所指向资源的大小(由getFIleLength方法实现),此处用到了URLConnection类,该类代表JAVA应用程序和URL之间的通信链接。

3、在本地磁盘上创建一个与网路资源相同大小的空文件。

4、计算每条线程应该下载网路资源的哪个部分(从哪个字节开始,到哪个字节结束)。

5、依次创建、启动多条线程来下载网路资源的指定部分。

URL 多线程下载的更多相关文章

  1. 多线程下载图片,同步下载http://www.importnew.com/15731.html

    package mutiDownload; import java.io.IOException; import java.io.InputStream; import java.io.RandomA ...

  2. Android学习记录(4)—在java中学习多线程下载的基本原理和基本用法①

    多线程下载在我们生活中非常常见,比如迅雷就是我们常用的多线程的下载工具,当然还有断点续传,断点续传我们在下一节来讲,android手机端下载文件时也可以用多线程下载,我们这里是在java中写一个测试, ...

  3. Java多线程下载文件

    package com.test.download;   import java.io.File; import java.io.InputStream; import java.io.RandomA ...

  4. java 网络编程基础 InetAddress类;URLDecoder和URLEncoder;URL和URLConnection;多线程下载文件示例

    什么是IPV4,什么是IPV6: IPv4使用32个二进制位在网络上创建单个唯一地址.IPv4地址由四个数字表示,用点分隔.每个数字都是十进制(以10为基底)表示的八位二进制(以2为基底)数字,例如: ...

  5. 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】

    一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...

  6. Java--使用多线程下载,断点续传技术原理(RandomAccessFile)

    一.基础知识 1.什么是线程?什么是进程?它们之间的关系? 可以参考之前的一篇文章:java核心知识点学习----并发和并行的区别,进程和线程的区别,如何创建线程和线程的四种状态,什么是线程计时器 简 ...

  7. android 多线程下载 断点续传

    来源:网易云课堂Android极客班第八次作业练习 练习内容: 多线程 asyncTask handler 多线程下载的原理 首先获取到目标文件的大小,然后在磁盘上申请一块空间用于保存目标文件,接着把 ...

  8. 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)

    1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...

  9. Java 仿迅雷多线程下载

    package net.webjoy.jackluo.android_json; /** * 1.http Range "bytes="+ start+end * 2.Random ...

随机推荐

  1. 制作pypi上的安装库

    下载地址 如何制作分发工具呢 setuppy 源码包 其他文件 制作过程 首先上场的肯定是setuppy了如下 然后是LICENCE 注册 测试 总结 自从接触Python以来也有几个月了,虽然主要的 ...

  2. Java使用agent实现main方法之前

    创建Agent项目 PreMainExecutor 类,在main方法之前执行此方法 public class PreMainExecutor { public static void premain ...

  3. actionbar详解(二)

    经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对较为深刻的理解了.唯一欠缺的是,前面我们都只是学习了理论知识而已,虽然知识点已经掌握了,但是真正投入到项目实战当中时会不会掉链子还很 ...

  4. SQL Server专家的10个秘诀(翻译加注解)

    当你点开这篇文章的时候,如果觉得没有读下去的必要,也希望你能拉到最后看看那几行字! 原文出处:https://technet.microsoft.com/en-us/magazine/gg299551 ...

  5. UIScrollView实现图片轮播器的无限滚动

    简介 在现在的一些App中常常见到图片轮播器,一般用于展示广告.新闻等数据,在iOS内并没有现成的控件直接实现这种功能,但是通过UIScrollView的允许分页设置,可以实现滚动轮播的功能. 轮播原 ...

  6. 一个 Linux 上分析死锁的简单方法

    简介 死锁 (deallocks): 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这 ...

  7. UNIX网络编程——揭开网络编程常见API的面纱【上】

    Linux网络编程API函数初步剖析 今天我们来分析一下前几篇博文中提到的网络编程中几个核心的API,探究一下当我们调用每个API时,内核中具体做了哪些准备和初始化工作. 1.socket(famil ...

  8. python+OpenCV 特征点检测

    1.Harris角点检测 Harris角点检测算法是一个极为简单的角点检测算法,该算法在1988年就被发明了,算法的主要思想是如果像素周围显示存在多于一个方向的边,我们认为该点为兴趣点.基本原理是根据 ...

  9. Java之恋

    初次见面那是一个河北的夏天风随沙散落天涯蝴蝶依旧恋着花回首走过的日子手指和键盘之间的梦想之光已恍如昨日 那年我还是一个刚踏进这个曾经只在地理课本上狂念南稻北麦,南油北花的土地那年你只是我必须要学的编程 ...

  10. Java进阶(三十七)java 自动装箱与拆箱

    Java进阶(三十七)java 自动装箱与拆箱 前言 这个是jdk1.5以后才引入的新的内容.java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装称为装箱,解包装称为 ...