Un hilo se puede entender como un canal de descarga. Un hilo es un canal de descarga de archivos. Múltiples hilos significa abrir varios canales de descarga al mismo tiempo. Cuando el servidor proporciona servicios de descarga, el descargador del usuario comparte el ancho de banda. Cuando la prioridad es la misma, el servidor total asignará uniformemente el hilo de descarga total. No es difícil de entender. Si tiene muchos hilos, cuanto más rápido lo descargará.
El popular software de descarga admite descargas de pausa de medio tiempo. Cuando comience de nuevo, no se descargará desde cero.
Los pasos para implementar las dos funciones son los siguientes:
(1) Al conectarse al archivo de recursos de descarga, primero determine el tamaño del archivo de recursos y cree un archivo temporal del mismo tamaño localmente para almacenar los datos de descarga.
(2) Determine el tamaño del archivo requerido para cada hilo en función del número de subprocesos
(3) Determine la ubicación de descarga de inicio y finalización de cada hilo de acuerdo con el tamaño del archivo y el número de subprocesos descargados por cada hilo, y determine la ubicación de descarga de inicio y finalización de cada hilo de acuerdo con el tamaño del archivo y el número de subprocesos descargados por cada subproceso.
(4) Para realizar la función de descarga de punto de interrupción, es necesario marcar la ubicación de la descarga en tiempo real de cada hilo para facilitar la descarga de progreso al principio la próxima vez.
Abra 3 vistas de descarga de hilos (el directorio de descarga predeterminado es un proyecto en Java):
El código de implementación general es el siguiente (todavía hay mucho espacio para la optimización, así que no solo miralo y está hecho)
import java.io.bufferedReader; import java.io.file; import java.io.fileInputStream; import java.io.inputStreamReader; import java.io.randomAccessFile; import java.net.httpurlConnection; import java.net.urL; = "http://soft3.xzstatic.com/2015/10/hsjj2ghgzh.rar"; public static int threadCount = 0; // declara el número de hilos public static void main (string [] args) {try {url url = new url (ruta); // Obtener la conexión httpurlconnection conn = (httpurlconnection) url.openconnection (); // Defina el nombre del archivo obteniendo la cadena de conexión [] str = path.split ("/"); Cadena filename = str [5]; // Obtener el archivo de descarga tamaño int filelength = conn.getContentLength (); System.out.println (nombre de archivo); // Cree un archivo escrito aleatoriamente que sea consistente con el tamaño del servidor localmente randomAtAccessFile RAF = new RandomAccessFile (nombre de archivo, "RWD"); System.out.println (Filelength); // prueba raf.setLength (fileLength); // recuento de subprocesos personalizado threadcount = 3; // Calcule el tamaño de los datos descargados por cada hilo int blocksize = filel longitud / threadcount; // Iniciar el código de hilo para (int threadid = 1; threadid <= threadCount; threadid ++) {// nore código, defina la ubicación de descarga en la que cada subproceso inicia y termina es int intar startPos = (threadid - 1) * blocksize; // la ubicación en la que la descarga inicia int endPos = (threadid * blocksize) - 1; // la ubicación en la que la descarga de la descarga (no incluye la última pieza) si ((si ((si está la última pieza) ((hilo de hilo de hilo). = Filelength; } nuevo hilo (nuevo descargarloadThread (threadid, startPos, endpos, ruta)) .Start (); }} catch (Exception e) {E.PrintStackTrace (); }} // Implementar el hilo de descarga de clase static downloadloadThread implementos runnable {private int threadid; Private int StartPos; privado int endpos; ruta de cadena privada; Public downloadloadThread (int threadid, int startPos, int endpos, string ruta) {super (); this.threadID = threadid; this.startpos = startPos; this.endpos = endpos; this.path = ruta; } public void run () {try {url url = new url (ruta); String [] str = path.split ("/"); Cadena filename = str [5]; Httpurlconnection conn = (httpurlconnection) url .openconnection (); // Establezca el método de solicitud de URL (consulte la API para obtener detalles) conn.setRequestMethod ("get"); // establecer 500 ms como el valor de tiempo de espera conn.setReadTimeOut (5000); Archivo archivo = nuevo archivo (threadid + ".txt"); if (file.exists () && file.length ()> 0) {bufferedReader br = new BufferedReader (new InputStreamReader (new FileInputStream (file))); String SaveStartPos = br.readline (); if (saveStartPos! = NULL && savestartPos.length ()> 0) {startpos = integer.ParseInt (saveStartPos); }} // Presta atención al formato en cotizaciones dobles, y no puede contener espacios (como otros caracteres), de lo contrario se informa 416. conn.setRequestProperty ("rango", "bytes =" + startPos + "-" + endPos); RandomAccessFile RAF = new RandomAccessFile (nombre de archivo, "rwd"); // almacenar el archivo de escritura aleatorio en el archivo de descarga raf.seek (startpos); // Establecer la ubicación para iniciar descargar system.out.println ("hilo" + threadid + ":" + startpos + "~~" + endPos); InputStream es = conn.getInputStream (); byte [] b = nuevo byte [1024 * 1024 * 10]; int len = -1; int newpos = startPos; while ((len = is.read (b))! = -1) {randomAccessFile rr = new RandomAccessFile (archivo, "rwd"); // el archivo que almacena la etiqueta de descarga raf.write (b, 0, len); // Guardar la etiqueta de descarga en el documento especificado String Savapoint = String.ValueOf (Newpos += Len); rr.write (savaPoint.getBytes ()); rr.close (); } is.close (); raf.close (); System.out.println ("Descargar completo"); } catch (Exception e) {E.PrintStackTrace (); }}}}Notas:
(1) Comprenda el método de cálculo de las posiciones de inicio y finalización de cada descarga de hilo (sin incluir el último hilo, comience desde 0)
Posición de inicio = (número de subprocesos - 1) * La longitud (tamaño) del archivo a descargar por cada hilo
Posición final = (número de hilos * Tamaño del archivo descargado por cada hilo) -1
(2) La posición de inicio de descarga asignada por el último hilo es la posición final del hilo anterior, y la posición final es la longitud del archivo.
Por lo tanto, la longitud del archivo descargada por el último hilo generalmente no será la misma que el hilo anterior
(3) La ruta de descarga de esta demostración es el directorio donde el proyecto Java se encuentra de forma predeterminada, y el directorio no puede contener archivos con el mismo nombre que el archivo descargado; de lo contrario, el programa informará un error de solicitud de red 416.
(4) Un error que cometí en la implementación conn.setRequestProperty ("rango", "bytes ="+startpos+"-"+endpos); Asegúrese de tener en cuenta que las citas no necesariamente tienen espacios adicionales y otros caracteres. Solo tengo un espacio en las cotizaciones, pero el posicionamiento de errores siempre ha sido un error de InputStream, y es muy doloroso encontrar las equivocadas.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.