Cet article décrit le téléchargement Java multi-thread. Partagez-le pour votre référence, comme suit:
L'utilisation de fichiers multi-thread pour télécharger des fichiers peut terminer le téléchargement des fichiers plus rapidement. La raison pour laquelle les fichiers multi-thread sont rapides est qu'ils occupent beaucoup de ressources de serveur. Par exemple: Supposons que le serveur sert jusqu'à 100 utilisateurs en même temps, et qu'un thread dans le serveur correspond à un utilisateur. 100 threads ne sont pas exécutés simultanément dans l'ordinateur, mais sont exécutés à leur tour par le CPU. Si l'application A utilise 99 threads pour télécharger des fichiers, il équivaut à occuper les ressources de 99 utilisateurs. Supposons que le temps d'exécution moyen alloué par le CPU à chaque thread dans une seconde est de 10 ms. Application A obtient un temps d'exécution de 990 ms en une seconde dans le serveur, tandis que d'autres applications n'ont que 10 ms d'exécution en une seconde. Tout comme un robinet, lorsque la production d'eau par seconde est égale, elle est définitivement plus d'eau pour 990 millisecondes que pour 10 millisecondes.
Le processus de mise en œuvre du téléchargement multithread:
1. Obtenez d'abord la longueur du fichier téléchargé, puis définissez la longueur du fichier local.
Httpurlconnection.getContentLength (); randomaccessfile file = new randomaccessfile ("youdao.exe", "rw"); file.setLength (fileSize); // définir la longueur du fichier local2. Calculez la longueur des données et le téléchargement de l'emplacement de chaque thread en fonction de la longueur du fichier et du nombre de threads. Par exemple: la longueur du fichier est de 6 m et le nombre de threads est de 3, alors la longueur des données téléchargées par chaque thread est de 2 m, et l'emplacement où chaque thread commence à télécharger est illustré dans la figure ci-dessous.
3. Utilisez le champ d'en-tête de plage de HTTP pour spécifier où chaque thread commence à télécharger, tel que: spécifiez le téléchargement du fichier à partir de la position 2M du fichier, le code est le suivant:
La copie de code est la suivante: httpurlconnection.setRequestProperty ("plage", "bytes = 2097152-");
4. Enregistrez le fichier et utilisez la classe RandomAccessFile pour spécifier où chaque thread commence à écrire des données dans le fichier local.
RandomAccessFile ThreadFile = new RandomAccessFile ("<span style =" font-Family: Arial, Helvetica, Sans-Serif; "> youdao.exe </span> <span style =" Font-Family: Arial, Helvetica, Sans-Serif; ">", "RW"); le fichierVoici la classe d'implémentation spécifique:
Avant d'écrire la classe d'implémentation, nous devons d'abord placer le fichier à télécharger sur le serveur et déployer:
Je le mets ici dans le répertoire d: /tomcat/apache-tomcat-7.0.37/webapps/doudou et démarrez le startup.bat sous d: /tomcat/apache-tomcat-7.0.37/bin
1.Dowloadtest.java
package www.csdn.net.down; import java.io.file; import java.io.fileInputStream; import java.io.fileoutputStream; import java.io.ioexception; import java.io.inputstream; java.net.malformedUrlexception; import java.net.url; public class downloadloadTest {public file file; Public RandomAccessFile AccessFile; // Nombre de threads public static int threadnum = 3; // Chaque thread est responsable du téléchargement INT BlockSize; // Créer le chemin d'accès public String Path = "http: // localhost: 8080 / Doudou / youdao.exe"; public static int threadCount; // Quantity public void testdown () {try {// Créer URL URL URL = new URL (path); // Créer un objet httpurlConnection httpurlconnection httpurlconnection = (httpurlconnection) url .openconnection (); // Définissez la méthode d'envoi de demandes httpurlconnection.setRequestMethod ("get"); // Définissez si le délai de demande httpurlconnection.setConnectTimeout (5000); // Définit httpurlConnection .SetRequestProperty ("User-Agent", "Mozilla / 5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident / 6.0)"); // si la réponse est réussie si (httpurlconnection.getResponSECODE () == 200) {// Obtenez le fichier size int size = httpurlconnection.getContentLength (); System.out.println ("Size de fichier" + taille); // Créer un fichier fichier = nouveau fichier ("youdao.exe"); AccessFile = new RandomAccessFile (fichier, "RWD"); // définir la taille du fichier AccessFile.SetLength (taille); // Téléchargez la taille de chaque thread blockSize = size / threadnum; // Ouvrez trois threads pour utiliser ce fichier pour (int i = 1; i <= threadnum; i ++) {// 1 2 3 // Calculez la position de départ de chaque thread int startize = (i - 1) * blockSize; // Position finale int fin = (i) * BlockSize; // Lorsque le thread est le dernier thread if (i == Threadnum) {// Déterminez si la taille du fichier est supérieure à la position d'extrémité calculée si (taille> finit) {// La position finale est égale à la taille du fichier EndSise = size; }} // Créer une lecture aléatoire pour chaque thread RandomAccessFile ThreadAccessFile = new RandomAccessFile (fichier, "rwd"); Nouveau thread (nouveau téléchargement (i, threadaccessfile, start size, chemin, chemin)). start (); }}} catch (MalformEdUrlexception e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } catch (ioException e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); }} public static void main (String [] args) {downloadTest downloadTest = new DownloadTest (); // Appelez la méthode de téléchargement DownloadTest.Testdown (); }} Class DownloadLoadThread implémente Runnable {// Encapsulation du fichier de téléchargement public RandomAccessFile ACCESSFILE; // Chaque thread a un objet de fichier AccessFile Thread1 Thread2 Thread3 // La position de départ du fichier de téléchargement de thread public int startize; le public intrigue; // Le chemin d'accès du fichier Téléchargez le chemin de la chaîne publique; public int threadid; // L'identification de Thread Public Downloadthread (int threadId, randomaccessfile AccessFile, int startize, int fin, String path) {this.ThreadId = ThreadId; this.AccessFile = AccessFile; this.startSize = startSize; this.endSize = finie; this.path = path; } @Override public void run () {// Exécuter la méthode d'exécution try {// créer un fichier file threadFile = new File (threadId + ".txt"); if (threadFile.exists ()) {// Lisez le contenu du fichier // Créer le flux d'entrée du fichier FileInputStream fis = new FileInputStream (ThreadFile); // Utilisez la classe d'outils pour lire les données d'octets [] = streamtools.istodata (FIS); // converti en chaîne de chaîne threadlen = new String (data); if ((threadlen! = null) && (! "". equals (threadlen))) {startsize = Integer.ValueOf (Threadlen); // Résolvez l'erreur de 416bug if (startize> finsi) {startsize = findSize - 1; }}} // Créer URL URL URL = new URL (chemin); // Créer un objet httpurlConnection httpurlconnection httpurlconnection = (httpurlconnection) url .openconnection (); // Définissez l'en-tête de demande httpurlconnection.setRequestMethod ("get"); // Définissez si le délai de demande httpurlconnection.setConnectTimeout (5000); // Définit httpurlConnection .SetRequestProperty ("User-Agent", "Mozilla / 5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident / 6.0)"); // Paramètres de clé httpurlconnection.setRequestProperty ("plage", "bytes =" + stardize + "-" + finsi); // Sortie du thread actuel System.out.println ("Thread actuel" + ThreadID + "Télécharger Position de démarrage:" + Démarrage + "Position de fin de téléchargement:" + EndSize); // Réponse réussie // Définissez la position de démarrage des fichiers de lecture aléatoires AccessFile.seek (startIze); // obtient l'objet Stream correspondant à sous est = httpurlconnection.getInputStream (); // Créer un tampon d'octet d'objet de flux de sortie [] = nouveau octet [1024]; int len = 0; int threadTotal = 0; // Enregistrer l'enregistrement après le téléchargement de chaque thread / while ((len = is.read (tampon))! = -1) {AccessFile.Write (Buffer, 0, Len); ThreadTotal + = len; // Enregistrez la longueur que vous écrivez // fichier xml // enregistrez la longueur du téléchargement du fichier via le fichier fileoutputStream fos = new FileOutputStream (ThreadFile); fos.write ((threadTotal + "") .getBytes ()); fos.flush (); fos.close (); } AccessFile.close (); is.close (); System.out.println (ThreadID + "L'exécution du thread est terminée"); // Opération de thread Synchronized (DownloadTest.Class) {téléchargementloadTest.ThreadCount ++; if (downloadTest.ThreadCount> = downloadloadTest.Threadnum) {for (int i = 1; i <= downloadTest.Threadnum; i ++) {file file = new File (i + ". txt"); if (file.exists ()) {file.delete (); }}}}} catch (MalformEdUrlexception e) {// TODO Block de catch généré automatiquement e.printStackTrace (); } catch (ioException e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); }}}2. Streamtools.java Encapsulation des outils de streaming
Package www.csdn.net.down; Importer java.io.bytearrayoutputStream; Importer java.io.ioException; import java.io.inputstream; public classe streamtools {byte statique public [] istodata (entrée est) lance ioException {// bytearrayoutPutStream bops = new bytearray (); // la zone de tampon pour la lecture du tampon d'octet de données [] = nouveau octet [1024]; // Lire l'enregistrement de la longueur int len = 0; // LECTURE DE LOOPE WHAD ((LEN = IS.REad (Buffer))! = -1) {bops.write (Buffer, 0, Len); } // Convertir le contenu de lecture en données d'octet de tableau d'octets [] = bops.tobytearray (); bops.flush (); bops.close (); is.close (); retourner les données; }}J'espère que cet article sera utile à la programmation Java de tous.