Dieser Artikel beschreibt den Multi-Thread-Java-Download. Teilen Sie es für Ihre Referenz wie folgt weiter:
Durch die Verwendung von Multi-Thread-Dateien zum Herunterladen von Dateien kann das Herunterladen von Dateien schneller abgeschlossen werden. Der Grund, warum Multi-Thread-Dateien schnell sind, ist, dass sie viele Serverressourcen belegen. Zum Beispiel: Angenommen, der Server dient gleichzeitig bis zu 100 Benutzer, und ein Thread im Server entspricht einem Benutzer. 100 Themen werden nicht gleichzeitig im Computer ausgeführt, sondern von der CPU ausgeführt. Wenn die Anwendung A 99 Threads zum Herunterladen von Dateien verwendet, entspricht es der Besetzung der Ressourcen von 99 Benutzern. Nehmen wir an, dass die durchschnittliche Ausführungszeit von der CPU für jeden Thread innerhalb einer Sekunde 10 ms beträgt. Anwendung A erhält 990 ms Ausführungszeit in einer Sekunde im Server, während andere Anwendungen nur 10 ms Ausführungszeit in einer Sekunde haben. Genau wie ein Wasserhahn ist es, wenn die Wasserleistung pro Sekunde gleich ist, definitiv mehr Wasser für 990 Millisekunden als für 10 Millisekunden.
Der Implementierungsprozess des Multi-Thread-Downloads:
1. Erhalten Sie zuerst die Länge der heruntergeladenen Datei und setzen Sie dann die Länge der lokalen Datei ein.
HttpurlConnection.getContentLength (); RandomAccessFile -Datei = new randomAccessfile ("yodao.exe", "rw"); Datei.setLength (Filesize); // Länge der lokalen Datei festlegen2. Berechnen Sie die Datenlänge und laden Sie den Speicherort jedes Threads basierend auf der Dateilänge und der Anzahl der Threads herunter. Zum Beispiel: Die Länge der Datei beträgt 6 m und die Anzahl der Threads beträgt 3, dann ist die von jedem Thread heruntergeladene Datenlänge 2 m und der Ort, an dem jeder Thread heruntergeladen wird, ist in der folgenden Abbildung angezeigt.
3.. Verwenden Sie das Feld "Range Header" von HTTP, um anzugeben, woher jeder Thread heruntergeladen wird, z. B.: Geben Sie die Datei -Download aus der 2 -m -Position der Datei an. Der Code lautet wie folgt:
Die Codekopie lautet wie folgt: httpurlConnection.setRequestProperty ("Bereich", "Bytes = 2097152-");
4. Speichern Sie die Datei und verwenden Sie die RandomAccessFile -Klasse, um anzugeben, wo jeder Thread anfängt, Daten in der lokalen Datei zu schreiben.
Randomaccessfile threadfile = new randomAccessfile ("<span style =" font-family: arial, helvetica, sans-serif; "> yodao.exe </span> <span style =" font-family: arial, helvetica, sans-serif; die DateiDas Folgende ist die spezifische Implementierungsklasse:
Vor dem Schreiben der Implementierungsklasse müssen wir die Datei erstmals auf dem Server herunterladen und bereitstellen:
Ich habe es hier in das Verzeichnis d: /tomcat/apache-tomcat-7.0.37/webapps/doudou gestellt und starten Sie die startup.bat unter d: /tomcat/apache-tomcat-7.0.37/bin
1.DownloadTest.java
Paket www.csdn.net.down; import java.io.file; import java.io.fileinputstream; import Java.io.fileOutputStream; Import Java.io.ioException; import Java.io.inputstream; Import Java.io.Randomaccessfile; Java.Net.NettpurlconlConlcinction; java.net.malFormedurlexception; importieren java.net.url; öffentliche Klasse DownloadLoadTest {öffentliche Dateidatei; public randomAccessfile accessFile; // Anzahl der Threads Public static int threadnum = 3; // Jeder Thread ist für das Herunterladen von Int Blocksize verantwortlich. // Erstellen Sie den Access Path Public String Path = "http: // localhost: 8080/doudou/yodao.exe"; public static int threadCount; // Quantity public void testdown () {try {// URL -Objekt url url = new url (path); // HttpurlConnection -Objekt httpurlConnection httpurlConnection = (httpurlConnection) url .OpenConnection (); // Stellen Sie die Methode zum Senden von Anforderungen httpurlConnection.setRequestMethod ("get") fest; // Legen Sie fest, ob die Anforderung Timeout httpurlConnection.setConnectTimeout (5000); // httpurlConnection .SetRequestProperty ("User-Agent", "Mozilla/5.0 (kompatibel; MSIE 10.0; Windows NT 6.2; Trident/6.0)") festlegen; // ob die Antwort erfolgreich ist, wenn (httpurlConnection.getresponseCode () == 200) {// Die Dateigröße int size = httpurlConnection.getContentLength () abrufen; System.out.println ("Dateigröße" + Größe); // Datei erstellen file = new Datei ("yodao.exe"); AccessFile = new randomAccessfile (Datei, "rwd"); // Setzen Sie die Dateigröße AccessFile.setLength (Größe); // Die Größe jedes Threads blockiert = Größe / Threadnum; // Öffnen Sie drei Threads, um diese Datei für (int i = 1; i <= threadnum; i ++) {// 1 2 3 // Berechnen Sie die Startposition jedes Threads int -starts = (i - 1) * blocksize; // Endposition int Endize = (i) * blocksize; // Wenn der Thread der letzte Thread ist, wenn (i == Threadnum) {// Bestimmen Sie, ob die Dateigröße größer ist als die berechnete Endposition, wenn (Größe> Endize) {// Die Endposition ist gleich der Dateigröße endete = Größe; }} // Erstellen Sie für jeden Thread RandomAccessfile threadAccessfile = new randomAccessfile (Datei, "rwd"); neuer Thread (neuer DownloadThread (i, ThreadAccessfile, startet, Endensize, Pfad). Start (); }}} catch (fehl Formaledurlexception e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } catch (ioException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); }} public static void main (String [] args) {downloadTest downloadTest = new DownloadTest (); // rufen Sie die Download -Methode downloadTest.TestDown () an; }} Klasse downloadLoadThread implementiert runnable {// Kapselung der Download -Datei public Accessfile AccessFile; // Jeder Thread verfügt über einen Zugriffsdatei -Objekt -Thread1 Thread2 Thread3 // Die Startposition der Thread -Download -Datei public Int startet startet. öffentlich int endet; // Der Pfad der Datei Download Public String Path; public int threadid; // Die Identifizierung von Thread Public DownloadThread (int threadID, randomAccessfile accessFile, int starts, int Endize, String -Pfad) {this.threadid = ThreadID; this.accessfile = AccessFile; this.StartSize = startsize; this.endsize = EndenSize; this.path = path; } @Override public void run () {// Führen Sie die Ausführungsmethode aus, versuchen Sie {// eine Dateidatei threadfile = new Datei (ThreadID + ".txt"); if (threadfile.exists ()) {// Lesen Sie den Inhalt der Datei // Erstellen Sie den Eingabestream -Objekt -Objektdatei -stream der Datei fis = new FileInputStream (ThreadFile); // Die Werkzeugklasse verwenden, um Byte -Daten zu lesen [] = streamtools.istodata (FIS); // in String String -String -Threadlen = new String (Daten) konvertieren; if ((threadlen! = null) && (! ". // den Fehler von 416bug lösen, wenn (startsize> endensize) {startSeize = EndSize - 1; }}} // URL -Objekt url = new URL (Pfad) erstellen; // HttpurlConnection -Objekt httpurlConnection httpurlConnection = (httpurlConnection) url .OpenConnection (); // Setzen Sie den Anforderungsheader httpurlConnection.setRequestMethod ("get"); // Legen Sie fest, ob die Anforderung Timeout httpurlConnection.setConnectTimeout (5000); // httpurlConnection .SetRequestProperty ("User-Agent", "Mozilla/5.0 (kompatibel; MSIE 10.0; Windows NT 6.2; Trident/6.0)") festlegen; // Schlüsseleinstellungen httpurlConnection.setRequestProperty ("Bereich", "bytes =" + startsgröße + "-" + EnderSize); // Ausgabe des aktuellen Thread -Systems.out.println ("Aktueller Thread" + ThreadID + "Startposition herunterladen:" + startsize + "download Endposition:" + endsize); // erfolgreiche Antwort // Setzen Sie die Startposition von zufälligen Lesedateien AccessFile.SEEK (STARTIZE); // Erhalten Sie den entsprechenden Stream -Objekt -Eingabestream is = httpurlConnection.getInputStream (); // Ausgabestream -Objekt -Byte -Buffer erstellen [] = neues Byte [1024]; int len = 0; int threadTotal = 0; // Datensatz speichern, nachdem jeder Thread heruntergeladen wurde/ while ((len = is.read (puffer))! = -1) {accessFile.write (Puffer, 0, len); ThreadTotal += len; // Aufzeichnen Sie die Länge, die Sie schreiben // XML -Datei // die Länge der Datei über den DateidateiOutputStream -Download fos = new FileOutputStream (ThreadFile) aufzeichnen. fos.write ((threadTotal + "") .getBytes ()); fos.flush (); fos.close (); } AccessFile.close (); IS.CLOSE (); System.out.println (ThreadID + "Thread -Ausführung ist abgeschlossen"); // Thread Operation Synchronized (downloadTest.class) {DownloadLoadTest.ThreadCount ++; if (downloadTest.threadCount> = downloadLoadTest.threadnum) {für (int i = 1; i <= downloadTest.threadnum; i ++) {Dateidatei = neue Datei (i+". txt"); if (file.exists ()) {file.delete (); }}}}} catch (fehl Formaledurlexception e) {// Todo automatisch generierter Catch Block E.PrintStacktrace (); } catch (ioException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); }}}2. Streamtools.java Kapselung von Streaming -Tools
Paket www.csdn.net.down; import Java.io.ByTearrayoutputStream; Import Java.io.ioxception; import Java.io.inputStream; öffentliche Klasse Streamtools {public static byte [] iStodata (InputStream löst ioException {// // ByteAntAutStream); // Der Pufferbereich zum Lesen von Daten Byte -Puffer [] = neues Byte [1024]; // LEAD LANGE BRAUT INT len = 0; // Loop -Lesung while ((len = is.read (puffer))! = -1) {bops.write (buffer, 0, len); } // den Leseinhalt in ein Byte -Array -Byte -Daten umwandeln [] = bops.tobytearray (); bops.flush (); BOPS.CLOSE (); IS.CLOSE (); Daten zurückgeben; }}Ich hoffe, dieser Artikel wird für Java -Programme aller hilfreich sein.