|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
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>
通过视频学习比传统的大课堂学习更适合成人化的学习规律。有人说大课堂气氛好,学习氛围浓,热闹,可以认识很多人。 |
|