2010-04-23 51 views
1

我想在下面的代碼中添加多個連接,以便能夠更快地下載文件。有人能幫助我嗎?提前致謝。Java多連接下載文件

public void run() { 
    RandomAccessFile file = null; 
    InputStream stream = null; 

    try { 
     // Open connection to URL. 
     HttpURLConnection connection = 
       (HttpURLConnection) url.openConnection(); 

     // Specify what portion of file to download. 
     connection.setRequestProperty("Range", 
       "bytes=" + downloaded + "-"); 

     // Connect to server. 
     connection.connect(); 

     // Make sure response code is in the 200 range. 
     if (connection.getResponseCode()/100 != 2) { 
      error(); 
     } 

     // Check for valid content length. 
     int contentLength = connection.getContentLength(); 
     if (contentLength < 1) { 
      error(); 
     } 

     /* Set the size for this download if it 
     hasn't been already set. */ 
     if (size == -1) { 
      size = contentLength; 
      stateChanged(); 
     } 

     // Open file and seek to the end of it. 
     file = new RandomAccessFile("C:\\"+getFileName(url), "rw"); 
     file.seek(downloaded); 

     stream = connection.getInputStream(); 
     while (status == DOWNLOADING) { 
      /* Size buffer according to how much of the 
      file is left to download. */ 
      byte buffer[]; 
      if (size - downloaded > MAX_BUFFER_SIZE) { 
       buffer = new byte[MAX_BUFFER_SIZE]; 
      } else { 
       buffer = new byte[size - downloaded]; 
      } 

      // Read from server into buffer. 
      int read = stream.read(buffer); 
      if (read == -1) { 
       break; 
      } 

      // Write buffer to file. 
      file.write(buffer, 0, read); 
      downloaded += read; 
      stateChanged(); 
     } 

     /* Change status to complete if this point was 
     reached because downloading has finished. */ 
     if (status == DOWNLOADING) { 
      status = COMPLETE; 
      stateChanged(); 
     } 
    } catch (Exception e) { 
     error(); 
    } finally { 
     // Close file. 
     if (file != null) { 
      try { 
       file.close(); 
      } catch (Exception e) { 
      } 
     } 

     // Close connection to server. 
     if (stream != null) { 
      try { 
       stream.close(); 
      } catch (Exception e) { 
      } 
     } 
    } 
} 
+0

你瞭解你已有的代碼嗎?因爲它看起來非常獨立,所有你需要做的就是創建多個實例並將它們傳遞給一個線程池。 – Anon 2010-04-23 19:22:58

+0

還有一個更基本的問題:爲什麼你認爲添加多個連接會讓你下載更快?除非您的服務器正在主動限制吞吐量,否則您將已經在使用接近完整的管道。 – Anon 2010-04-23 19:24:41

+1

@Anon:這是一個常見的伎倆。它有助於在到服務器的RTT不能保持管道充滿時(無論帶寬多少,每個RTT最多1個接收器窗口),可以獲得更多連接。當你在某處遇到擁塞時,它也會有所幫助,因爲TCP試圖給每個*連接一個公平的份額。更多的連接,更多的份額,更多的帶寬。然而,你不可能有連接數量的線性增量。 – PypeBros 2011-06-17 10:25:56

回答

1

您可以使用線程。

將下載和更新RandomAccessFile的代碼放入Thread/Runnable中,並啓動它的多個實例。

使用全局計數器(同步訪問)跟蹤有多少線程完成下載,並使主線程等待,直到所有線程在關閉文件之前增加了計數器。

確保同步對RandomAccessFile的所有訪問,以便在線程B正在寫入文件的另一部分時線程A不能調用seek(somePosition)

+2

而不是在一個'RandomAccessFile'上同步,給每個線程自己的文件,讓操作系統管理磁盤緩衝區的同步。 – Anon 2010-04-23 19:22:01

0

確保你描述你想出的東西。多線程的開銷和它們之間的協調可能會讓你的代碼變慢。 不要這樣做,除非你確定這是一個瓶頸,代碼的複雜性會增加,調試這是不平凡的。