仓酷云
标题:
来看Java手艺体验:HTTP多线程下载,端口侦听和自启动服务
[打印本页]
作者:
再现理想
时间:
2015-1-18 11:17
标题:
来看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[BUFFER_SIZE];
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
如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。
作者:
莫相离
时间:
2015-1-27 05:05
不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
作者:
若天明
时间:
2015-2-4 21:48
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
作者:
谁可相欹
时间:
2015-2-9 22:45
是一种使用者不需花费很多时间学习的语言
作者:
海妖
时间:
2015-2-10 08:06
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
作者:
爱飞
时间:
2015-2-22 22:45
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
作者:
分手快乐
时间:
2015-3-7 03:58
应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
作者:
愤怒的大鸟
时间:
2015-3-11 10:39
让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。
作者:
小妖女
时间:
2015-3-12 15:21
任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言
作者:
小女巫
时间:
2015-3-19 23:23
设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧
欢迎光临 仓酷云 (http://ckuyun.com/)
Powered by Discuz! X3.2