当前位置:七道奇文章资讯编程技术Java编程
日期:2011-03-22 16:13:00  来源:本站整理

Java技术体验:HTTP多线程下载,端口侦听和自启动服务[Java编程]

赞助商链接



  本文“Java技术体验:HTTP多线程下载,端口侦听和自启动服务[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

一个网友恰好需求这个东西,我就把几个技术整合到了一同.包含三个部份,实现时也是一一做到的

多线程的文件下载,HTTP协议

把这个功效做成一个HTTP的服务,侦听在某个端口上,便利非Java的系统利用

把这个功效封装为一个Windows服务,在机械启动时可以自动启动

我们一一看程序.

1、多线程下载

这个主要利用了HTTP协议里面的一个Range参数,他设置了你读取数据的其实位置和终止位置. 常常利用flashget的用户在查看衔接的具体信息时,应当常常看到这个东西.比方

Range:bytes=100-2000

代表从100个字节的位置开始读取,到2000个字节的位置完毕,应读取1900个字节.

程序首先拿到文件的长度,然后分配几个线程去辨别读取各自的一段,利用了

RandomAccessFile

举行随机位置的读写.

下面是完好的下载的代码.

package net.java2000.tools;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
/**
* HTTP的多线程下载工具.
*
* @author 赵学庆 www.java2000.net
*/
public class HTTPDownloader extends Thread {
  // 要下载的页面
  private String page;
  // 保存的途径
  private String savePath;
  // 线程数
  private int threadNumber = 2;
  // 根源地址
  private String referer;
  // 最小的块尺寸.假如文件尺寸除以线程数小于这个,则会削减线程数.
  private int MIN_BLOCK = 10 * 1024;
  public static void main(String[] args) throws Exception {
   HTTPDownloader d = new HTTPDownloader("http://www.xxxx.net/xxxx.rar", "d://xxxx.rar", 10);
   d.down();
  }
  public void run() {
   try {
    down();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  /**
  * 下载操作
  *
  * @throws Exception
  */
  public void down() throws Exception {
   URL url = new URL(page); // 成立URL
   URLConnection con = url.openConnection(); // 成立衔接
   int contentLen = con.getContentLength(); // 得到资源长度
   if (contentLen / MIN_BLOCK + 1 < threadNumber) {
    threadNumber = contentLen / MIN_BLOCK + 1; // 调整下载线程数
   }
   if (threadNumber > 10) {
    threadNumber = 10;
   }
   int begin = 0;
   int step = contentLen / threadNumber;
   int end = 0;
   for (int i = 0; i < threadNumber; i++) {
    end += step;
    if (end > contentLen) {
     end = contentLen;
    }
    new HTTPDownloaderThread(this, i, begin, end).start();
    begin = end;
   }
  }
  public HTTPDownloader() {
  }
  /**
  * 下载
  *
  * @param page 被下载的页面
  * @param savePath 保存的途径
  */
  public HTTPDownloader(String page, String savePath) {
   this(page, savePath, 10);
  }
  /**
  * 下载
  *
  * @param page 被下载的页面
  * @param savePath 保存的途径
  * @param threadNumber 线程数
  */
  public HTTPDownloader(String page, String savePath, int threadNumber) {
   this(page, page, savePath, 10);
  }
  /**
  * 下载
  *
  * @param page 被下载的页面
  * @param savePath 保存的途径
  * @param threadNumber 线程数
  * @param referer 根源
  */
  public HTTPDownloader(String page, String referer, String savePath, int threadNumber) {
   this.page = page;
   this.savePath = savePath;
   this.threadNumber = threadNumber;
   this.referer = referer;
  }
  public String getPage() {
   return page;
  }
  public void setPage(String page) {
   this.page = page;
  }
  public String getSavePath() {
   return savePath;
  }
  public void setSavePath(String savePath) {
   this.savePath = savePath;
  }
  public int getThreadNumber() {
   return threadNumber;
  }
  public void setThreadNumber(int threadNumber) {
   this.threadNumber = threadNumber;
  }
  public String getReferer() {
   return referer;
  }
  public void setReferer(String referer) {
   this.referer = referer;
  }
}
/**
* 下载线程
*
* @author 赵学庆 www.java2000.net
*/
class HTTPDownloaderThread extends Thread {
  HTTPDownloader manager;
  int startPos;
  int endPos;
  int id;
  int curPos;
  int BUFFER_SIZE = 4096;
  int readByte = 0;
  HTTPDownloaderThread(HTTPDownloader manager, int id, int startPos, int endPos) {
   this.id = id;
   this.manager = manager;
   this.startPos = startPos;
   this.endPos = endPos;
  }
  public void run() {
   // System.out.println("线程" + id + "启动");
   // 成立一个buff
   BufferedInputStream bis = null;
   RandomAccessFile fos = null;
   // 缓冲区大小
   byte[] buf = new byte[BUFFER_SIZE];
   URLConnection con = null;
   try {
    File file = new File(manager.getSavePath());
    // 成立RandomAccessFile
    fos = new RandomAccessFile(file, "rw");
    // 从startPos开始
    fos.seek(startPos);
    // 成立衔接,这里会为每个线程都成立一个衔接
    URL url = new URL(manager.getPage());
    con = url.openConnection();
    con.setAllowUserInteraction(true);
    curPos = startPos;
    // 设置获得资源数据的范围,从startPos到endPos
    con.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
    // 盗链办理
    con.setRequestProperty("referer", manager.getReferer() == null ? manager.getPage() : manager.getReferer());
    con.setRequestProperty("userAgent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
    // 下面一段向按照文件写入数据,curPos为当前写入的未知,这里会判断能否小于endPos,
    // 假如超越endPos就代表该线程已经履行完毕
    bis = new BufferedInputStream(con.getInputStream());
    while (curPos < endPos) {
     int len = bis.read(buf, 0, BUFFER_SIZE);
     if (len == -1) {
      break;
     }
     fos.write(buf, 0, len);
     curPos = curPos + len;
     if (curPos > endPos) {
      // 获得精确读取的字节数
      readByte += len - (curPos - endPos) + 1;
     } else {
      readByte += len;
     }
    }
    // System.out.println("线程" + id + "已经下载完毕:" + readByte);
    bis.close();
    fos.close();
   } catch (IOException ex) {
    ex.printStackTrace();
   }
  }
}


  以上是“Java技术体验:HTTP多线程下载,端口侦听和自启动服务[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • 利用Javascript实现网页水印(非图片水印)
  • Java开辟环境的搭建
  • Ubuntu java安装与配置
  • 办理Ubuntu 10.04 Firefox3.6 Java浏览器插件不工作的问
  • Ubuntu重装后Java环境的设置
  • Sun Java进入Ubuntu 10.10软件中央
  • Ubuntu 10.10配置Java开辟环境
  • 在Ubuntu 10.10中配置Java环境变量的办法
  • Ubuntu下Java环境的搭建
  • Ubuntu 10.04 下安装 Java, JRE
  • Ubuntu 10.04下的搭建SUN JAVA开辟环境
  • Ubuntu 12.04安装java7
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .