?? 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 + -