再现理想 发表于 2015-1-18 11:17:28

来看Java手艺体验:HTTP多线程下载,端口侦听和自启动服务

ruby里有这些工具吗?又要简单多少?我没有用过这两门语言,我估计在这些语言力没有很统一的这种标准,或者根本就没有提供。
一个网友恰好必要这个工具,我就把几个手艺整合到了一同。包含三个部分,完成时也是逐一做到的
多线程的文件下载,HTTP协定
把这个功效做成一个HTTP的服务,侦听在某个端口上,便利非Java的体系利用
把这个功效封装为一个Windows服务,在呆板启动时能够主动启动
我们逐一看程序。
1、多线程下载
这个次要利用了HTTP协定内里的一个Range参数,他设置了你读取数据的实在地位和停止地位。常常利用flashget的用户在检察毗连的具体信息时,应当常常看到这个工具。好比
Range:bytes=100-2000
代表从100个字节的地位入手下手读取,到2000个字节的地位停止,应读取1900个字节。
程序起首拿到文件的长度,然后分派几个线程往分离读取各自的一段,利用了
RandomAccessFile
举行随机地位的读写。
上面是完全的下载的代码。
packagenet.java2000.tools;
importjava.io.BufferedInputStream;
importjava.io.File;
importjava.io.IOException;
importjava.io.RandomAccessFile;
importjava.net.URL;
importjava.net.URLConnection;
/**
*HTTP的多线程下载工具。
*
*@author赵学庆www.java2000.net
*/
publicclassHTTPDownloaderextendsThread{
 //要下载的页面
 privateStringpage;
 //保留的路径
 privateStringsavePath;
 //线程数
 privateintthreadNumber=2;
 //来历地点
 privateStringreferer;
 //最小的块尺寸。假如文件尺寸除以线程数小于这个,则会削减线程数。
 privateintMIN_BLOCK=10*1024;
 publicstaticvoidmain(String[]args)throwsException{
  HTTPDownloaderd=newHTTPDownloader("http://www.xxxx.net/xxxx.rar","d://xxxx.rar",10);
  d.down();
 }
 publicvoidrun(){
  try{
   down();
  }catch(Exceptione){
   e.printStackTrace();
  }
 }
 /**
 *下载操纵
 *
 *@throwsException
 */
 publicvoiddown()throwsException{
  URLurl=newURL(page);//创立URL
  URLConnectioncon=url.openConnection();//创建毗连
  intcontentLen=con.getContentLength();//取得资本长度
  if(contentLen/MIN_BLOCK+1<threadNumber){
   threadNumber=contentLen/MIN_BLOCK+1;//调剂下载线程数
  }
  if(threadNumber>10){
   threadNumber=10;
  }
  intbegin=0;
  intstep=contentLen/threadNumber;
  intend=0;
  for(inti=0;i<threadNumber;i++){
   end+=step;
   if(end>contentLen){
    end=contentLen;
   }
   newHTTPDownloaderThread(this,i,begin,end).start();
   begin=end;
  }
 }
 publicHTTPDownloader(){
 }
 /**
 *下载
 *
 *@parampage被下载的页面
 *@paramsavePath保留的路径
 */
 publicHTTPDownloader(Stringpage,StringsavePath){
  this(page,savePath,10);
 }
 /**
 *下载
 *
 *@parampage被下载的页面
 *@paramsavePath保留的路径
 *@paramthreadNumber线程数
 */
 publicHTTPDownloader(Stringpage,StringsavePath,intthreadNumber){
  this(page,page,savePath,10);
 }
 /**
 *下载
 *
 *@parampage被下载的页面
 *@paramsavePath保留的路径
 *@paramthreadNumber线程数
 *@paramreferer来历
 */
 publicHTTPDownloader(Stringpage,Stringreferer,StringsavePath,intthreadNumber){
  this.page=page;
  this.savePath=savePath;
  this.threadNumber=threadNumber;
  this.referer=referer;
 }
 publicStringgetPage(){
  returnpage;
 }
 publicvoidsetPage(Stringpage){
  this.page=page;
 }
 publicStringgetSavePath(){
  returnsavePath;
 }
 publicvoidsetSavePath(StringsavePath){
  this.savePath=savePath;
 }
 publicintgetThreadNumber(){
  returnthreadNumber;
 }
 publicvoidsetThreadNumber(intthreadNumber){
  this.threadNumber=threadNumber;
 }
 publicStringgetReferer(){
  returnreferer;
 }
 publicvoidsetReferer(Stringreferer){
  this.referer=referer;
 }
}
/**
*下载线程
*
*@author赵学庆www.java2000.net
*/
classHTTPDownloaderThreadextendsThread{
 HTTPDownloadermanager;
 intstartPos;
 intendPos;
 intid;
 intcurPos;
 intBUFFER_SIZE=4096;
 intreadByte=0;
 HTTPDownloaderThread(HTTPDownloadermanager,intid,intstartPos,intendPos){
  this.id=id;
  this.manager=manager;
  this.startPos=startPos;
  this.endPos=endPos;
 }
 publicvoidrun(){
  //System.out.println("线程"+id+"启动");
  //创立一个buff
  BufferedInputStreambis=null;
  RandomAccessFilefos=null;
  //缓冲区巨细
  byte[]buf=newbyte;
  URLConnectioncon=null;
  try{
   Filefile=newFile(manager.getSavePath());
   //创立RandomAccessFile
   fos=newRandomAccessFile(file,"rw");
   //从startPos入手下手
   fos.seek(startPos);
   //创立毗连,这里会为每一个线程都创立一个毗连
   URLurl=newURL(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;MSIE6.0;WindowsNT5.1)");
   //上面一段向依据文件写进数据,curPos为以后写进的未知,这里会判别是不是小于endPos,
   //假如凌驾endPos就代表该线程已实行终了
   bis=newBufferedInputStream(con.getInputStream());
   while(curPos<endPos){
    intlen=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(IOExceptionex){
   ex.printStackTrace();
  }
 }
}
<p>
通过视频学习比传统的大课堂学习更适合成人化的学习规律。有人说大课堂气氛好,学习氛围浓,热闹,可以认识很多人。

冷月葬花魂 发表于 2015-1-22 15:55:45

如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。

莫相离 发表于 2015-1-27 05:05:21

不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。

若天明 发表于 2015-2-4 21:48:20

Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。

谁可相欹 发表于 2015-2-9 22:45:52

是一种使用者不需花费很多时间学习的语言

海妖 发表于 2015-2-10 08:06:28

一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从

爱飞 发表于 2015-2-22 22:45:45

有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)

分手快乐 发表于 2015-3-7 03:58:44

应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展

愤怒的大鸟 发表于 2015-3-11 10:39:03

让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。

小妖女 发表于 2015-3-12 15:21:31

任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言

小女巫 发表于 2015-3-19 23:23:43

设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧
页: [1]
查看完整版本: 来看Java手艺体验:HTTP多线程下载,端口侦听和自启动服务