Este artículo describe la descarga de Java de múltiples subprocesos. Compártelo para su referencia, como sigue:
El uso de archivos de múltiples subprocesos para descargar archivos puede completar la descarga de archivos más rápido. La razón por la cual los archivos múltiples son rápidos es que ocupan muchos recursos del servidor. Por ejemplo: suponga que el servidor sirve hasta 100 usuarios al mismo tiempo, y un hilo en el servidor corresponde a un usuario. 100 hilos no se ejecutan simultáneamente en la computadora, sino que la CPU ejecuta a su vez. Si la aplicación A usa 99 hilos para descargar archivos, es equivalente a ocupar los recursos de 99 usuarios. Suponga que el tiempo de ejecución promedio asignado por la CPU a cada hilo dentro de un segundo es de 10 ms. La aplicación A obtiene el tiempo de ejecución de 990 ms en un segundo en el servidor, mientras que otras aplicaciones solo tienen un tiempo de ejecución de 10 ms en un segundo. Al igual que un grifo, cuando la salida de agua por segundo es igual, definitivamente es más agua para 990 milisegundos que para 10 milisegundos.
El proceso de implementación de la descarga de múltiples subprocesos:
1. Primero obtenga la longitud del archivo descargado y luego establezca la longitud del archivo local.
Httpurlconnection.getContentLength (); randomAccessFile file = new RandomAccessFile ("YouDaoo.exe", "RW"); File.SetLength (filesize); // Establezca la longitud del archivo local2. Calcule la longitud de los datos y la ubicación de descarga de cada hilo en función de la longitud del archivo y el número de subprocesos. Por ejemplo: la longitud del archivo es de 6m y el número de subprocesos es 3, entonces la longitud de los datos descargados por cada subproceso es de 2 m, y la ubicación donde cada hilo comienza a descargar en la figura a continuación.
3. Use el campo de encabezado de rango de HTTP para especificar dónde comienza a descargar cada hilo, como: Especifique la descarga del archivo desde la posición 2M del archivo, el código es el siguiente:
La copia del código es la siguiente: httpurlconnection.setRequestProperty ("rango", "bytes = 2097152-");
4. Guarde el archivo y use la clase RandomAccessFile para especificar dónde comienza a escribir datos cada hilo en el archivo local.
RandomAccessFile ThreadFile = new RandomACcessFile ("<Span Style =" Font-Family: Arial, Helvetica, Sans-Serif; "> Yoidao.exe </span> <span span style =" Font-Family: Arial, Helvetica, Sans-Serif; ">", "RW"); </span> Threadfile.seek (2097152); donde en el archivoLa siguiente es la clase de implementación específica:
Antes de escribir la clase de implementación, primero debemos colocar el archivo para descargar en el servidor e implementar:
Lo puse aquí en el directorio d: /tomcat/apache-tomcat-7.0.37/webapps/doudou e inicie startup.bat en d: /tomcat/apache-mocat-7.0.37/bin
1.DownloadTest.java
paquete 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; importar java.net.httpurlconnection; java.net.malFormedUrePLECTION; import java.net.url; public class downloadloadTest {archivo de archivo público; Public RandomAccessFile AccessFile; // Número de hilos public static int threadnum = 3; // Cada hilo es responsable de descargar Int BlockSize; // Crear la ruta de acceso de la ruta pública Path = "http: // localhost: 8080/doudou/youdao.exe"; public static int threadCount; // Cantidad public void testdown () {try {// Crear objeto URL url url = new url (ruta); // Crear objeto httpurlconnection httpurlconnection httpurlconnection = (httpurlconnection) url .openconnection (); // Establezca el método para enviar solicitudes httpurlconnection.setRequestMethod ("get"); // Establecer si el tiempo de espera de la solicitud httpurlConnection.setConnectTimeOut (5000); // establecer httpurlconnection .SetRequestProperty ("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // si la respuesta es exitosa si (httpurlconnection.getResponseCode () == 200) {// obtiene el tamaño del archivo int size = httpurlconnection.getContentLength (); System.out.println ("tamaño de archivo" + tamaño); // Crear archivo Archivo = nuevo archivo ("YouDao.exe"); accessfile = new RandomAccessFile (archivo, "rwd"); // Establecer el tamaño del archivo AccessFile.SetLength (tamaño); // Descargar el tamaño de cada hilo blocksize = size / threadnum; // Abra tres subprocesos para operar este archivo para (int i = 1; i <= threadnum; i ++) {// 1 2 3 // Calcule la posición inicial de cada subproceso INT inicia = (i - 1) * blockSize; // End Position int finalize = (i) * blockSize; // Cuando el hilo es el último hilo if (i == threadnum) {// Determine si el tamaño del archivo es mayor que la posición final calculada si (size> terminalize) {// La posición final es igual al tamaño del archivo terminalSe = size; }} // Cree una lectura aleatoria para cada hilo randomAtAccessFile ThreadAccessFile = new RandomAccessFile (archivo, "RWD"); nuevo hilo (nuevo DownloadThread (I, ThreadAccessFile, inicia, termina, ruta)). Start (); }}} Catch (MalFormedUrLeCeption e) {// TODO BLOQUE DE CABTA GENERADA AUTO } Catch (ioException e) {// tODO Auto Generated BLOCK E.PrintStackTRace (); }} public static void main (string [] args) {downloadTest downloadTest = new downloadTest (); // Llame al método de descarga descargartest.testdown (); }} class downloadLoadThread implementos runnable {// encapsulación del archivo de descarga public randomAtAssSfile accessFile; // Cada hilo tiene un objeto de archivo AccessFile Thread1 Thread2 Thread3 // La posición inicial del archivo de descarga de subproceso Public int inicia; público int termina; // La ruta de ruta del archivo descarga la ruta de cadena pública; público int threadid; // La identificación de Thread Public Downloadthread (int ThreadID, RandomAccessFile AccessFile, int inicia, int termina, string ruta) {this.threadID = threadID; this.accessfile = accessfile; this.StartSize = inicio; this.endesize = termina; this.path = ruta; } @Override public void run () {// Ejecutar el método Ejecutar pruebe {// Crear un archivo File ThreadFile = New File (ThreadID + ".txt"); if (threadfile.exists ()) {// lee el contenido del archivo // Cree el objeto de entrada de entrada del archivo FileInputStream Fis = new FileInputStream (ThreadFile); // Use la clase de herramientas para leer datos de bytes [] = streamtools.istodata (FIS); // Convertir a String String ThreadLen = New String (Data); if ((threadlen! = null) && (! "". Equals (threadlen))) {inicio = integer.valueOf (threadlen); // Resuelve el error de 416bug if (startize> terminalize) {startsize = terminalize - 1; }}} // Crear objeto URL url url = new url (ruta); // Crear objeto httpurlconnection httpurlconnection httpurlconnection = (httpurlconnection) url .openconnection (); // Establecer el encabezado de solicitud httpurlconnection.setRequestMethod ("get"); // Establecer si el tiempo de espera de la solicitud httpurlConnection.setConnectTimeOut (5000); // establecer httpurlconnection .SetRequestProperty ("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // Configuración de clave httpurlconnection.setRequestProperty ("rango", "bytes =" + comienza + "-" + termina); // Salida del hilo actual System.out.println ("Hild actual" + threadid + "Descargar la posición de inicio:" + inicia + "Descargar la posición final:" + terminalize); // respuesta exitosa // Establecer la posición de inicio de los archivos de lectura aleatoria AccessFile.seek (inicio); // Obtener el objeto de transmisión correspondiente InputStream es = httpurlconnection.getInputStream (); // Crear búfer de byte de objeto de transmisión de salida [] = nuevo byte [1024]; int len = 0; int threadtotal = 0; // Guardar registro después de descargar cada hilo/ while ((len = is.read (buffer))! = -1) {accessFile.write (buffer, 0, len); ThreadTotal += Len; // Registre la longitud que escribe // archivo xml // registra la longitud del archivo descarga a través del archivo fileoutputStream fos = new outputStream (Threadfile); fos.write ((threadtotal + "") .getBytes ()); fos.flush (); fos.close (); } AccessFile.Close (); is.close (); System.out.println (threadid + "se completa la ejecución de subprocesos"); // subproceso de operación sincronizado (downloadTest.class) {downloadloadTest.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 (malformedurexception e) {// tODO BLOQUE DE CABTA AUTO GENERADA E.PRINTSTACKTRACE (); } Catch (ioException e) {// tODO Auto Generated BLOCK E.PrintStackTRace (); }}}2. StreamTools.Java Encapsulación de herramientas de transmisión
paquete www.csdn.net.down; import java.io.bytearRayOutputStream; import java.io.ioexception; import java.io.inputStream; public class Streamtools {public static byte [] istodata (inputStream is) lanza ioexception {// byteArTrayReam bops = new byteArrayAutraam ();); // El área del búfer para leer datos de bytes de datos [] = nuevo byte [1024]; // Leer longitud de registro int len = 0; // Lectura de bucle while ((len = is.read (buffer))! = -1) {bops.write (buffer, 0, len); } // Convierta el contenido de lectura en datos de byte de matriz de byte [] = bops.tobytearray (); bops.flush (); bops.close (); is.close (); devolver datos; }}Espero que este artículo sea útil para la programación Java de todos.