现在的位置: 首页 > 综合 > 正文

java 多线程断点下载

2014年11月27日 ⁄ 综合 ⁄ 共 9024字 ⁄ 字号 评论关闭

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.Ostermiller.util.Base64;

public class MuliThreadBreakPointDown {
 
 private String path = "http://apache.mirror.phpchina.com/struts/source/struts-2.0.11.1-src.zip";
 private static int ARRAY_LEN=1024;
 private int threadCount = 1;
 private ThreadDownLoadData[] downs = new ThreadDownLoadData[threadCount];
 private String outputFilePath ="c:/struts.zip";
 private String outputConfigPaht = "c:/struts.txt";
 private long [] beginBorders = new long[threadCount];
 private boolean hasProxy = true ;
 
 class MyHttpInputStream {
  private InputStream inputStream;
  private long beginBorder ;
  private void getRemoteInputStream() {
   try {
    URL url = new URL(path);
    HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
    if ( hasProxy )
     setHttpProxy(httpUrl);
    httpUrl.setRequestProperty("RANGE", "bytes=" + beginBorder + "-"); //这是很关键地方
    inputStream = httpUrl.getInputStream();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  public InputStream getInputStream() {
   getRemoteInputStream();
   return inputStream;
  }
  public void setInputStream(InputStream inputStream) {
   this.inputStream = inputStream;
  }
  public long getBeginBorder() {
   return beginBorder;
  }
  public void setBeginBorder(long beginBorder) {
   this.beginBorder = beginBorder;
  }
 }

 class ThreadDownLoadData extends Thread {
  private InputStream inputStream;
  private long beginBorder;
  private long endBorder ;
  private RandomAccessFile writeDiskrandomFile ;
  public ThreadBreakPointMsg threadBreakPointMsg ;
  private int threadNo ;
  public ThreadBreakPointMsg getThreadBreakPointMsg() {
   return threadBreakPointMsg;
  }
  public void setThreadBreakPointMsg(ThreadBreakPointMsg threadMsg) {
   this.threadBreakPointMsg = threadMsg;
  }
  public int getThreadNo() {
   return threadNo;
  }
  public void setThreadNo(int threadIndex) {
   this.threadNo = threadIndex;
  }
  public InputStream getInputStream() {
   return inputStream;
  }
  public void setInputStream(InputStream inputStream) {
   this.inputStream = inputStream;
  }
  public long getBeginBorder() {
   return beginBorder;
  }
  public void setBeginBorder(long beginBorder) {
   this.beginBorder = beginBorder;
  }
  public long getEndBorder() {
   return endBorder;
  }
  public void setEndBorder(long endBorder) {
   this.endBorder = endBorder;
  }
  public void run () {
   if ( inputStream != null )
   {
    try {
     RandomAccessFile randmsg =threadBreakPointMsg.getRandomThreadMsgFile() ;
     byte[] b= new byte[ARRAY_LEN];
     int arrayIndex = 0;
     while ( (beginBorder< endBorder) && (  (arrayIndex = inputStream.read(b, 0, b.length) )!=-1 ) )
     {
      writeDiskrandomFile.seek(beginBorder);
      if ( (beginBorder + arrayIndex) > endBorder ){
       writeDiskrandomFile.write(b,0, (int)(endBorder - beginBorder) );
       arrayIndex = (int)(endBorder - beginBorder);
      } else
       writeDiskrandomFile.write(b,0,arrayIndex );
      beginBorder=beginBorder + arrayIndex ;
      Long seekIndex = threadBreakPointMsg.getSeekAxis().get( threadNo );
      randmsg.seek( seekIndex );
      String  str = randmsg.readLine();
      if ( str != null ) {
       int length = str.length();
       String newStr = "thread["+ (threadNo+1) +"]=" + beginBorder ;
       length = length -newStr.length();
       String space = "";
       for(int i=0;i< length ; i++){
        space = space + " ";
       }
       newStr = newStr + space + "/r/n";
       byte[] datas2 = newStr.getBytes();
       randmsg.seek( seekIndex );
       randmsg.write(datas2, 0, datas2.length); //回写已下载的位置
   }
     }
     
     int counter = 0;
     for(int i=0;i<downs.length;i++) {
      if ( downs[i].getState().toString().equalsIgnoreCase("TERMINATED") ) {
       counter = counter + 1;
      }
     }
     if ( counter== (threadCount-1)) {
      writeDiskrandomFile.close();
      randmsg.close();
      inputStream.close();
     }
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  }
  public RandomAccessFile getWriteDiskrandomFile() {
   return writeDiskrandomFile;
  }
  public void setWriteDiskrandomFile(RandomAccessFile randomFile) {
   this.writeDiskrandomFile = randomFile;
  }
 }
 
 public void deal () {
  File outConfigFile = new File(outputConfigPaht);
  File outDataFile = new File(outputFilePath);
  RandomAccessFile randomThreadMsgFile = null;
  RandomAccessFile randomFile = null;
  try {
   randomThreadMsgFile = new RandomAccessFile(outConfigFile,"rw");
   randomFile = new RandomAccessFile(outDataFile,"rw");
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }
  ThreadBreakPointMsg threadMsg = new ThreadBreakPointMsg();
  threadMsg.setThreadCount(threadCount);
  threadMsg.setRandomThreadMsgFile(randomThreadMsgFile);
  boolean isBreakFlag = false ;
  try {
   if ( !outConfigFile.exists() ||  (outConfigFile.length()==0 ))
    threadMsg.createThreadBreakPointMsg();
   else {
    threadMsg.initThreadBreakPointMsg();
    isBreakFlag = true ;
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  
  long fileSize = getFileSize();
  long  averageSize = fileSize/threadCount;
  long counter = fileSize - averageSize ;
  
  for(int i=0;i<threadCount;i++) {
   downs[i] = new ThreadDownLoadData();
   MyHttpInputStream myInputStream = new MyHttpInputStream();
   if ( isBreakFlag ) {
    if ( beginBorders[i] ==0 ){
     downs[i].setBeginBorder(fileSize - (counter+averageSize) );
    }
    else {
     myInputStream.setBeginBorder(beginBorders[i]);
    }
   }
   else {
    downs[i].setBeginBorder(fileSize - (counter+averageSize) );
   }
   myInputStream.setBeginBorder(downs[i].getBeginBorder());
   downs[i].setInputStream( myInputStream.getInputStream());
   
   if ( i< (threadCount-1)){
    downs[i].setEndBorder( fileSize - counter);
   }
   else {
    downs[i].setEndBorder( fileSize );
   }
   System.out.println("downs["+i+"]"+downs[i].getEndBorder()  );
   downs[i].setWriteDiskrandomFile(randomFile);
   downs[i].setThreadBreakPointMsg(threadMsg);
   downs[i].setThreadNo(i);
   counter = counter - averageSize;
  }
  
  for(int i=0;i<threadCount;i++){
   downs[i].start();
  }
  
 }
 
 
 private void setHttpProxy(HttpURLConnection httpUrl  ) {
  System.getProperties().put(   "http.proxyPort",   "8080");
  System.getProperties().put(   "http.proxyHost",   "192.168.0.1");    
  System.getProperties().put(   "http.proxySet",   "true"   );    
  httpUrl.setRequestProperty(   "Proxy-Authorization",   "Basic   "   +   Base64.encode(  "yourName"   +   ":"   +   "yourKey"   )   );
 }
 
 public long getFileSize( ){
  int fileLength=-1;
        try
        {
            URL url=new URL(path);
            HttpURLConnection httpUrl=(HttpURLConnection) (url.openConnection());
            if ( hasProxy )
             setHttpProxy(httpUrl);
            int responseCode=httpUrl.getResponseCode();
            if(responseCode>=400)
            {
                System.out.println("Web服务器响应错误");
                return -2;
            }
            String sHeader;
            for(int i=1;;i++)
            {
                sHeader=httpUrl.getHeaderFieldKey(i);
                if(sHeader!=null)
                {
                    if(sHeader.equals("Content-Length"))
                    {
                        fileLength=Integer.parseInt(httpUrl.getHeaderField(sHeader));
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return fileLength;
  }

 class ThreadBreakPointMsg {
  private int threadCount;
  private RandomAccessFile randomThreadMsgFile;
  private List<Long> seekAxis = new ArrayList<Long>();

  public RandomAccessFile getRandomThreadMsgFile() {
   return randomThreadMsgFile;
  }

  public void setRandomThreadMsgFile(RandomAccessFile randomThreadMsgFile) {
   this.randomThreadMsgFile = randomThreadMsgFile;
  }

  public void createThreadBreakPointMsg() {
   try {
    byte[] datas = ("threadCount=" + threadCount + "/r/n").getBytes();
    randomThreadMsgFile.seek(0);
    randomThreadMsgFile.write(datas, 0, datas.length);
    Long seekIndex = new Long(datas.length);
    for (int i = 0; i < threadCount; i++) {
     seekAxis.add(seekIndex);
     randomThreadMsgFile.seek(seekIndex);
     byte[]datas2 = ("thread["+(i+1)+"]=0           /r/n").getBytes();
     randomThreadMsgFile.write(datas2, 0, datas2.length);
     seekIndex = seekIndex + datas2.length;
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }

  public void initThreadBreakPointMsg() {
   try {
    randomThreadMsgFile.seek(0);
    String line = randomThreadMsgFile.readLine();
    byte[] datas = (line +"/r/n").getBytes();
    Long seekIndex = new Long(datas.length);
    for (int i = 0; i < threadCount; i++) {
     seekAxis.add(seekIndex);
     line = randomThreadMsgFile.readLine();
     int position = line.indexOf("=")+1;
     beginBorders[i] = Long.parseLong(line.substring(position,line.length()).trim() );
     byte[] datas2 = (line+"/r/n").getBytes();
     seekIndex = seekIndex + datas2.length;
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  public int getThreadCount() {
   return threadCount;
  }

  public void setThreadCount(int threadCount) {
   this.threadCount = threadCount;
  }

  public List<Long> getSeekAxis() {
   return seekAxis;
  }

  public void setSeekAxis(List<Long> seekAxis) {
   this.seekAxis = seekAxis;
  }
 }
 
 public static void main(String[] args) throws Exception {
  MuliThreadBreakPointDown main = new MuliThreadBreakPointDown();
  main.deal();
 }
}

抱歉!评论已关闭.