2010-04-23 20 views
1

Je voulais ajouter plusieurs connexions dans le code ci-dessous pour pouvoir télécharger des fichiers plus rapidement. Quelqu'un pourrait-il m'aider? Merci d'avance.Connexions multiples Java téléchargement de fichier

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

Comprenez-vous le code que vous avez déjà? Parce qu'il semble très autonome, et tout ce que vous devez faire est de créer plusieurs instances et de les passer à un pool de threads. – Anon

+0

Et une question plus fondamentale: pourquoi croyez-vous que l'ajout de plusieurs connexions vous permettra de télécharger plus rapidement? À moins que votre serveur ne ralentisse activement le débit, vous l'utiliserez déjà à proximité du pipeline complet. – Anon

+1

@Anon: c'est un truc commun. Cela permet d'avoir plus de connexions lorsque le RTT vers le serveur est tel que vous ne pouvez pas garder le tuyau plein (votre max est de 1 fenêtre de réception par RTT, quelle que soit la bande passante). Cela aide également lorsque vous rencontrez de la congestion quelque part, car TCP essaie de donner à chaque * connexion * une part équitable. Plus de connexions, plus de partages, plus de bande passante. Cependant, il est peu probable que vous ayez un incrément linéaire avec le nombre de connexions. – PypeBros

Répondre

1

Vous pouvez utiliser des unités d'exécution.

Mettez le code pour télécharger et mettre à jour le RandomAccessFile dans un Thread/Runnable et démarrer plusieurs instances de celui-ci.

Utilisez un compteur global (accès synchronisé) pour connaître le nombre de threads terminés le téléchargement et attendez que tous les threads aient augmenté le compteur avant de fermer le fichier.

Assurez-vous de synchroniser tous les accès au RandomAccessFile, afin que le thread A ne puisse pas appeler seek(somePosition) pendant que le thread B écrit dans une autre partie du fichier.

+2

Plutôt que de synchroniser sur un seul 'RandomAccessFile', donnez à chaque thread son propre fichier et laissez le système d'exploitation gérer la synchronisation au niveau du buffer de disque. – Anon

0

Assurez-vous de profiler ce que vous venez avec. Il est possible que l'overhead de plusieurs threads et la coordination entre eux puissent vous rendre le code plus lent. Ne le faites pas à moins d'être certain qu'il s'agit d'un goulot d'étranglement, la complexité du code augmentera et le débogage est non-trivial.