zoukankan      html  css  js  c++  java
  • 《安卓网络编程》之第四篇 处理URL地址

      在Android手机系统中,可以通过URL地址获取网络资源。在URL类的众多方法中,可以使用openStream()方法来读取该URL资源的输入流InputStream。在此方法的基础上可以引申出很多重要的应用。在URL中,可以使用方法openConnection()返回一个URLConnection对象,该对象表示应用程序和URL之间的通信连接。程序可以通过URLConnection实例向该URL发送请求、读取URL引用的资源。

    下面的例子是在JAVA环境下使用URL实现多线程下载:

    多线程类DownTHhread

     1 import java.io.*;
     2 
     3 //定义下载从start到end的内容的线程
     4 class DownThread extends Thread {
     5     // 定义字节数组(取水的竹筒)的长度
     6     private final int BUFF_LEN = 32;
     7     // 定义下载的起始点
     8     private long start;
     9     // 定义下载的结束点
    10     private long end;
    11     // 下载资源对应的输入流
    12     private InputStream is;
    13     // 将下载到的字节输出到raf中
    14     private RandomAccessFile raf;
    15     
    16     // 构造器,传入输入流,输出流和下载起始点、结束点
    17     public DownThread(long start, long end, InputStream is, RandomAccessFile raf) {
    18         // 输出该线程负责下载的字节位置
    19         System.out.println(start + "---->" + end);
    20         this.start = start;
    21         this.end = end;
    22         this.is = is;
    23         this.raf = raf;    
    24     }
    25 
    26     public void run() {
    27         try {
    28             is.skip(start);
    29             raf.seek(start);
    30             // 定义读取输入流内容的缓存数组(竹筒)
    31             byte[] buff = new byte[BUFF_LEN];
    32             // 本线程负责下载资源的大小
    33             long contentLen = end - start;
    34             // 定义最多需要读取几次就可以完成本线程的下载
    35             long times = contentLen / BUFF_LEN + 4;
    36             // 实际读取的字节数
    37             int hasRead = 0;
    38             for (int i = 0; i < times; i++) {
    39                 hasRead = is.read(buff);
    40                 // 如果读取的字节数小于0,则退出循环!
    41                 if (hasRead < 0) {
    42                     break;
    43                 }
    44                 raf.write(buff, 0, hasRead);
    45             }
    46         } catch (Exception ex) {
    47             ex.printStackTrace();
    48         }
    49         // 使用finally块来关闭当前线程的输入流、输出流
    50         finally {
    51             try {
    52                 if (is != null) {
    53                     is.close();
    54                 }
    55                 if (raf != null) {
    56                     raf.close();
    57                 }
    58             } catch (Exception ex) {
    59                 ex.printStackTrace();
    60             }
    61         }
    62     }
    63 }

    类MutilDown:

     1 import java.io.*;
     2 import java.net.*;
     3 
     4 public class MutilDown {
     5     public static void main(String[] args) {
     6         final int DOWN_THREAD_NUM = 4;
     7         final String OUT_FILE_NAME = "down.jpg";
     8         InputStream[] isArr = new InputStream[DOWN_THREAD_NUM];
     9         RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];
    10         try {
    11             // 创建一个URL对象
    12             URL url = new URL("http://images.china-pub.com/"
    13                     + "ebook35001-40000/35850/shupi.jpg");
    14             // 以此URL对象打开第一个输入流
    15             isArr[0] = url.openStream();
    16             long fileLen = getFileLength(url);
    17             System.out.println("网络资源的大小" + fileLen);
    18             // 以输出文件名创建第一个RandomAccessFile输出流
    19             outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw");
    20             // 创建一个与下载资源相同大小的空文件
    21             for (int i = 0; i < fileLen; i++) {
    22                 outArr[0].write(0);
    23             }
    24             // 每线程应该下载的字节数
    25             long numPerThred = fileLen / DOWN_THREAD_NUM;
    26             // 整个下载资源整除后剩下的余数
    27             long left = fileLen % DOWN_THREAD_NUM;
    28             for (int i = 0; i < DOWN_THREAD_NUM; i++) {
    29                 // 为每个线程打开一个输入流、一个RandomAccessFile对象,
    30                 // 让每个线程分别负责下载资源的不同部分。
    31                 if (i != 0) {
    32                     // 以URL打开多个输入流
    33                     isArr[i] = url.openStream();
    34                     // 以指定输出文件创建多个RandomAccessFile对象
    35                     outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
    36                 }
    37                 // 分别启动多个线程来下载网络资源
    38                 if (i == DOWN_THREAD_NUM - 1) {
    39                     // 最后一个线程下载指定numPerThred+left个字节
    40                     new DownThread(i * numPerThred, (i + 1) * numPerThred
    41                             + left, isArr[i], outArr[i]).start();
    42                 } else {
    43                     // 每个线程负责下载一定的numPerThred个字节
    44                     new DownThread(i * numPerThred, (i + 1) * numPerThred,
    45                             isArr[i], outArr[i]).start();
    46                 }
    47             }
    48         } catch (Exception ex) {
    49             ex.printStackTrace();
    50         }
    51     }
    52 
    53     // 定义获取指定网络资源的长度的方法
    54     // 定义获取指定网络资源的长度的方法
    55     public static long getFileLength(URL url) throws Exception {
    56         long length = 0;
    57         // 打开该URL对应的URLConnection。
    58         URLConnection con = url.openConnection();
    59         // 获取连接URL资源的长度
    60         long size = con.getContentLength();
    61         length = size;
    62         return length;
    63     }
    64 }

    上面的代码中类MutilDown按如下步骤实现多线程下载:

    1. 创建URL对象。
    2. 获取指定URL对象所指向资源的大小(由getFileLength方法实现),此处用到了URLConnection类,该类代表Java应用程序和URL之间的通信链接。
    3. 在本地磁盘上创建一个与网络资源相同大小的空文件。
    4. 计算每条线程应该下载网络资源的哪个部分(从哪个字节开始,到哪个字节结束)。
    5. 依次创建、启动多条线程来下载网络资源的指定部分。

    程序运行结果:

    网络资源的大小69281
    0---->17320
    17320---->34640
    34640---->51960
    51960---->69281

    工程对应目录会出现down.jpg

  • 相关阅读:
    监控平台
    自动化配置管理
    软件课程设计(15)
    软件课程设计(14)
    软件课程设计(13)
    软件课程设计(12)
    软件课程设计(11)
    软件课程设计(10)
    软件课程设计(9)
    参考资料
  • 原文地址:https://www.cnblogs.com/hixin/p/4365705.html
Copyright © 2011-2022 走看看