📄 httpdownload.java
字号:
package download;import javax.swing.UIManager;import java.awt.*;import java.io.DataOutputStream;import java.net.HttpURLConnection;import java.io.IOException;import java.io.FileInputStream;import java.net.URL;import java.io.File;import java.io.DataInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.Serializable;import java.io.RandomAccessFile;//Java实现网络文件传输,在客户端请求Web服务器传输指定文件,并将文件保存。public class HttpDownload { private String sWebAddr = "http://kent.dl.sourceforge.net/sourceforge/jamper/Sample.zip"; // 定义Web地址和文件名 // 例如,传输http://cs.bnu.edu.cn/source/vb/地址的vb.zip 则 sWebAddr = "http://cs.bnu.edu.cn/source/vb/vb.zip" private String sSavePath = "d:\\temp"; // 定义存文件路径 private String sSaveName = "sample.zip"; // 定义文件名 public HttpDownload(){ try{ CacthInfo bean = new CacthInfo(sWebAddr,sSavePath,sSaveName,5); CacthFile fileFetch = new CacthFile(bean); fileFetch.start(); } catch(Exception e){ e.printStackTrace (); } } public static void main(String[] args){ new HttpDownload(); }}class CacthFile extends Thread { // 传输文件线程类 CacthInfo siteInfoBean = null; //文件信息Bean long[] nPos; long[] nStartPos; //开始位置 long[] nEndPos; //结束位置 PartCacth[] fileSplitterFetch; //子线程对象 long nFileLength; //文件长度 boolean bFirst = true; //是否第一次取文件 boolean bStop = false; //停止标志 File tmpFile; //文件传输临时信息 DataOutputStream output; //输出到文件的输出流 public CacthFile(CacthInfo bean) throws IOException{ siteInfoBean = bean; tmpFile = new File(bean.getSFilePath()+File.separator + bean.getSFileName()+".info"); if(tmpFile.exists ()){ bFirst = false; read_nPos(); } else{ nStartPos = new long[bean.getNSplitter()]; nEndPos = new long[bean.getNSplitter()]; } } public void run(){ //获得文件长度 //分割文件 //实例PartCacth //启动PartCacth线程 //等待子线程返回 try{ if(bFirst){ nFileLength = getFileSize(); if(nFileLength == -1){ System.err.println("File Length is not known!"); } else if(nFileLength == -2){ System.err.println("File is not access!"); } else{ for(int i=0;i<nStartPos.length;i++){ nStartPos[i] = (long)(i*(nFileLength/nStartPos.length)); } for(int i=0;i<nEndPos.length-1;i++){ nEndPos[i] = nStartPos[i+1]; } nEndPos[nEndPos.length-1] = nFileLength; } } //启动子线程 fileSplitterFetch = new PartCacth[nStartPos.length]; for(int i=0;i<nStartPos.length;i++){ fileSplitterFetch[i] = new PartCacth(siteInfoBean.getSSiteURL(), siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName(), nStartPos[i],nEndPos[i],i); Addtion.log("Thread " + i + " , nStartPos = " + nStartPos[i] + ", nEndPos = " + nEndPos[i]); fileSplitterFetch[i].start(); } //等待子线程结束 //int count = 0; //是否结束while循环 boolean breakWhile = false; while(!bStop){ write_nPos(); Addtion.sleep(500); breakWhile = true; for(int i=0;i<nStartPos.length;i++){ if(!fileSplitterFetch[i].bDownOver){ breakWhile = false; break; } } if(breakWhile) break; } System.out.println("文件传输结束!"); } catch(Exception e){ e.printStackTrace (); } } //获得文件长度 public long getFileSize(){ int nFileLength = -1; try{ URL url = new URL(siteInfoBean.getSSiteURL()); HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection (); httpConnection.setRequestProperty("User-Agent","NetFox"); int responseCode=httpConnection.getResponseCode(); if(responseCode>=400){ processErrorCode(responseCode); return -2; //-2 为Web服务器响应错误 } String sHeader; for(int i=1;;i++){ sHeader=httpConnection.getHeaderFieldKey(i); if(sHeader!=null){ if(sHeader.equals("Content-Length")){ nFileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader)); break; } } else break; } } catch(IOException e){e.printStackTrace ();} catch(Exception e){e.printStackTrace ();} Addtion.log(nFileLength); return nFileLength; } //保存传输信息(文件指针位置) private void write_nPos(){ try{ output = new DataOutputStream(new FileOutputStream(tmpFile)); output.writeInt(nStartPos.length); for(int i=0;i<nStartPos.length;i++){ // output.writeLong(nPos[i]); output.writeLong(fileSplitterFetch[i].nStartPos); output.writeLong(fileSplitterFetch[i].nEndPos); } output.close(); } catch(IOException e){e.printStackTrace ();} catch(Exception e){e.printStackTrace ();} } //读取保存的下载信息(文件指针位置) private void read_nPos(){ try{ DataInputStream input = new DataInputStream(new FileInputStream(tmpFile)); int nCount = input.readInt(); nStartPos = new long[nCount]; nEndPos = new long[nCount]; for(int i=0;i<nStartPos.length;i++){ nStartPos[i] = input.readLong(); nEndPos[i] = input.readLong(); } input.close(); //判断每块的文件开始位置是否大于结束位置 for(int i=0;i<nStartPos.length;i++){ if(nStartPos[i]>nEndPos[i]){ nStartPos[i]=nEndPos[i]; } } } catch(IOException e){e.printStackTrace ();} catch(Exception e){e.printStackTrace ();} } private void processErrorCode(int nErrorCode){ System.err.println("Error Code : " + nErrorCode); } //停止文件传输 public void siteStop(){ bStop = true; for(int i=0;i<nStartPos.length;i++) fileSplitterFetch[i].splitterStop(); }}class CacthInfo { // 定义获取和设置相关文件信息类 private String sSiteURL; // 定义URL变量 private String sFilePath; // 定义存文件路径变量 private String sFileName; // 定义文件名变量 private int nSplitter; // 定义传输文件计数值 public CacthInfo(){ this("","","",5); // 设置传输文件计数值 } public CacthInfo(String sURL,String sPath,String sName,int nSpiltter){ sSiteURL= sURL; sFilePath = sPath; sFileName = sName; this.nSplitter = nSpiltter; } public String getSSiteURL(){ return sSiteURL; } public void setSSiteURL(String value){ sSiteURL = value; } public String getSFilePath(){ return sFilePath; } public void setSFilePath(String value){ sFilePath = value; } public String getSFileName(){ return sFileName; } public void setSFileName(String value){ sFileName = value; } public int getNSplitter(){ return nSplitter; } public void setNSplitter(int nCount){ nSplitter = nCount; }}class PartCacth extends Thread { String sURL; // 定义文件传输时使用的变量 long nStartPos; // 分段文件传输开始位置 long nEndPos; // 分段文件传输结束位置 int nThreadID; // 子线程ID boolean bDownOver = false; // 完成文件传输 boolean bStop = false; // 停止文件传输 StoreFile fileAccess = null; public PartCacth(String sURL,String sName,long nStart,long nEnd,int id) throws IOException{ this.sURL = sURL; this.nStartPos = nStart; this.nEndPos = nEnd; nThreadID = id; fileAccess = new StoreFile(sName,nStartPos); } public void run(){ while(nStartPos < nEndPos && !bStop){ try{ URL url = new URL(sURL); HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection (); httpConnection.setRequestProperty("User-Agent","NetFox"); String sProperty = "bytes="+nStartPos+"-"; httpConnection.setRequestProperty("RANGE",sProperty); Addtion.log(sProperty); InputStream input = httpConnection.getInputStream(); byte[] b = new byte[1024]; int nRead; while((nRead=iput.read(b,0,1024)) > 0 && nStartPos <nEndPos && !bStop){ nStartPos += fileAccess.write(b,0,nRead); } Addtion.log("Thread " + nThreadID + " is over!"); bDownOver = true; } catch(Exception e){ e.printStackTrace (); } } bDownOver = true; } public void logResponseHead(HttpURLConnection con){ for(int i=1;;i++){ String header=con.getHeaderFieldKey(i); if(header!=null) Addtion.log(header+" : "+con.getHeaderField(header)); else break; } } public void splitterStop(){ bStop = true; }}class StoreFile implements Serializable{ // 定义访问文件类 RandomAccessFile oSavedFile; long nPos; public StoreFile() throws IOException{ this("",0); } public StoreFile(String sName,long nPos) throws IOException{ oSavedFile = new RandomAccessFile(sName,"rw"); this.nPos = nPos; oSavedFile.seek(nPos); } public synchronized int write(byte[] b,int nStart,int nLen){ int n = -1; try{ oSavedFile.write(b,nStart,nLen); n = nLen; } catch(IOException e){ e.printStackTrace (); } return n; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -