Paket cn.me.test;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
java.net.URL importieren;
/**
*Multithread-Download
*1: Verwenden Sie RandomAccessFile, um Daten an einen beliebigen Ort zu schreiben.
*2: Die vom ersten Thread heruntergeladene Datenmenge muss berechnet werden und kann gleichmäßig verteilt werden. Wenn es nicht durchschnittlich genug ist,
* Dann verarbeitet der letzte Thread direkt relativ kleine Daten
*3: Dateien gleicher Größe müssen vor dem Herunterladen vorbereitet und über den Dateiheader abgerufen werden
*/
öffentliche Klasse MultiThreadDownload {
public static void main(String[] args) löst eine Ausnahme aus {
//1: Deklarieren Sie den Dateinamen und die Download-Adresse
String fileName = "aa.rar";
String urlStr = "http://localhost:7777/day18";
//2: URL deklarieren
URL url = neue URL(urlStr+"/"+fileName);
//3: Verbindung herstellen
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
//4:Legen Sie die Anforderungsmethode fest
con.setRequestMethod("GET");
//5: Holen Sie sich den Anforderungsheader, der der Länge der Datei entspricht
int length = con.getContentLength();//Ermitteln Sie die Länge der heruntergeladenen Datei, um die Datenmenge zu berechnen, die jeder Thread herunterladen sollte.
//6: Erstellen Sie eine Datei derselben Größe im angegebenen Verzeichnis
RandomAccessFile file = new RandomAccessFile("d:/a/"+fileName, "rw");//Eine Datei derselben Größe erstellen.
//7: Dateigröße festlegen, Platzhalter
file.setLength(length);//Legen Sie die Dateigröße fest.
file.close();
//8: Definieren Sie die Anzahl der Threads
int-Größe = 3;
//9: Berechnen Sie, wie viele Datenbytes jeder Thread herunterladen soll. Wenn es genau teilbar ist, ist es am besten, andernfalls 1 hinzuzufügen
int block = length/size==0?length/size:length/size+1;// Berechnen Sie die Datenmenge, die jeder Thread herunterladen soll.
System.err.println("Jeder Thread sollte herunterladen: "+block);
//10: Führen Sie drei Threads aus und berechnen Sie, welches Byte beginnt und endet
for(int i=0;i<size;i++){
int start = i*block;
int end = start+(block-1);//Berechnen Sie die Start- und Endbytes jedes Threads.
System.err.println(i+"="+start+","+end);
new MyDownThread(fileName, start, end,url).start();
}
}
Die statische Klasse MyDownThread erweitert Thread{
//Dateinamen definieren
privater String fileName;
//Definieren Sie, wo mit dem Herunterladen begonnen werden soll
privater int start;
//Definieren Sie, in welches Byte heruntergeladen werden soll
private Absicht Ende;
private URL-URL;
public MyDownThread(String fileName,int start,int end,URL url){
this.fileName=fileName;
this.start=start;
this.end=end;
this.url=url;
}
@Override
public void run() {
versuchen{
//11: Download starten
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//12: Legen Sie den Anforderungsheader für segmentierte Downloads fest
con.setRequestProperty("Range","bytes="+start+"-"+end);//Legen Sie die vom Server gelesenen Dateiblöcke fest.
//13: Download starten, muss 206 beurteilen
if(con.getResponseCode()==206){//Der Zugriff ist erfolgreich, der zurückgegebene Statuscode ist 206.
InputStream in = con.getInputStream();
//14: Deklarieren Sie ein zufälliges Schreibdateiobjekt. Beachten Sie, dass sich rwd auf das sofortige Schreiben von Daten in die Datei bezieht, ohne den Cache-Bereich zu verwenden.
RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);//Legen Sie fest, dass das Schreiben von Daten ab einer bestimmten Position in der Datei beginnen soll.
byte[] b=neues Byte[1024];
int len = 0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
out.close();
in.close();
}
System.err.println(this.getName()+"Ausführung abgeschlossen");
}catch(Ausnahme e){
throw new RuntimeException(e);
}
}
}
}