paquete cn.me.test;
importar java.io.InputStream;
importar java.io.RandomAccessFile;
importar java.net.HttpURLConnection;
importar java.net.URL;
/**
*Descarga multiproceso
*1: Utilice RandomAccessFile para escribir datos en cualquier ubicación.
*2: La cantidad de datos descargados por el primer hilo debe calcularse y puede distribuirse uniformemente. Si no es lo suficientemente promedio,
* Luego, el último hilo procesa directamente datos relativamente pequeños
*3: Los archivos del mismo tamaño deben prepararse antes de descargarlos y obtenerse a través del encabezado del archivo.
*/
clase pública MultiThreadDownload {
public static void main (String [] args) lanza una excepción {
//1: declarar el nombre del archivo y la dirección de descarga
Nombre de archivo de cadena = "aa.rar";
Cadena urlStr = "http://localhost:7777/day18";
//2: declarar URL
URL URL = nueva URL(urlStr+"/"+fileName);
//3: Obtener la conexión
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
//4:Establecer el método de solicitud
con.setRequestMethod("OBTENER");
//5: obtiene el encabezado de la solicitud, que es la longitud del archivo
int length = con.getContentLength();//Obtenga la longitud del archivo descargado para calcular la cantidad de datos que debe descargar cada hilo.
//6: crea un archivo del mismo tamaño en el directorio especificado
Archivo RandomAccessFile = new RandomAccessFile("d:/a/"+fileName, "rw");//Crea un archivo del mismo tamaño.
//7: Establecer tamaño de archivo, marcador de posición
file.setLength(length);//Establece el tamaño del archivo.
archivo.close();
//8: Definir el número de hilos
tamaño entero = 3;
//9: Calcule cuántos bytes de datos debe descargar cada hilo. Si es exactamente divisible, es mejor; de lo contrario, agregue 1.
int block = length/size==0?length/size:length/size+1;// Calcula la cantidad de datos que debe descargar cada hilo.
System.err.println("Cada hilo debe descargarse: "+bloque);
//10: ejecuta tres subprocesos y calcula qué byte comienza y termina
para(int i=0;i<tamaño;i++){
int inicio = i*bloque;
int end = start+(block-1);//Calcula los bytes de inicio y fin de cada hilo.
System.err.println(i+"="+inicio+","+fin);
new MyDownThread(nombre de archivo, inicio, fin,url).start();
}
}
clase estática MyDownThread extiende Thread{
//Definir nombre de archivo
nombre de archivo de cadena privada;
//Definir dónde empezar a descargar
inicio int privado;
//Definimos a qué byte descargar
extremo de intención privada;
URL privada;
público MyDownThread (nombre de archivo de cadena, inicio int, fin int, URL URL) {
this.fileName=nombredearchivo;
this.start=iniciar;
this.end=fin;
this.url=url;
}
@Anular
ejecución pública vacía() {
intentar{
//11: Iniciar la descarga
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
con.setRequestMethod("OBTENER");
//12: Establecer el encabezado de solicitud para descargas segmentadas
con.setRequestProperty("Range","bytes="+start+"-"+end);//Establece los bloques de archivos leídos desde el servidor.
//13: Comienza a descargar, necesitas juzgar 206
if(con.getResponseCode()==206){//El acceso es exitoso, el código de estado devuelto es 206.
InputStream en = con.getInputStream();
// 14: Declarar un objeto de archivo de escritura aleatoria. Tenga en cuenta que rwd se refiere a escribir datos en el archivo inmediatamente sin utilizar el área de caché.
RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);// Configurado para comenzar a escribir datos desde una determinada posición en el archivo.
byte[] b=nuevo byte[1024];
int longitud = 0;
mientras((len=in.read(b))!=-1){
out.write(b,0,len);
}
fuera.cerrar();
cercar();
}
System.err.println(this.getName()+"Ejecución completada");
}catch(Excepción e){
lanzar nueva RuntimeException(e);
}
}
}
}