Um tópico pode ser entendido como um canal de download. Um tópico é um canal de download de arquivos. Vários tópicos significa abrir vários canais de download ao mesmo tempo. Quando o servidor fornece serviços de download, o usuário download compartilha a largura de banda. Quando a prioridade for a mesma, o servidor total alocará uniformemente o thread de download total. Não é difícil de entender. Se você tem muitos threads, quanto mais rápido o baixar.
O software de download popular suporta downloads multi-threading e suporta pausas intermediárias. Quando você começar de novo, você não será baixado do zero.
As etapas para implementar as duas funções são as seguintes:
(1) Ao conectar -se ao arquivo de recursos de download, primeiro determine o tamanho do arquivo de recursos e crie um arquivo temporário do mesmo tamanho localmente para armazenar os dados de download.
(2) Determine o tamanho do arquivo necessário para cada thread com base no número de threads
(3) Determine a localização do download de início e final de cada tópico de acordo com o tamanho do arquivo e o número de threads baixados por cada thread e determine o local de download inicial e final de cada thread de acordo com o tamanho do arquivo e o número de threads baixados por cada thread.
(4) Para realizar a função de download do ponto de interrupção, é necessário marcar a localização do download em tempo real de cada thread para facilitar o download do progresso no início da próxima vez.
Open 3 Thread Download Views (o diretório de download padrão é um projeto em Java):
O código geral de implementação é o seguinte (ainda há muito espaço para otimização, então não olhe para ele e está feito)
importar java.io.bufferedReader; importar java.io.file; importar java.io.fileInputStream; importar java.io.inputStreamReader; importar java.io.randomaccessfile; import redarearling downloads downloads; String Path = "http://soft3.xzstatic.com/2015/10/hsjj2ghgzh.rar"; public static int threadCount = 0; // Declare o número de threads public static void main (string [] args) {try {url url = new url (caminho); // Obtenha a conexão httpurlConnection Conn = (httpurlConnection) url.openconnection (); // Defina o nome do arquivo, obtendo a conexão string [] str = path.split ("/"); String filename = str [5]; // Obtenha o tamanho do arquivo de download int fileLength = Conn.getContentLength (); System.out.println (nome do arquivo); // Crie um arquivo escrito aleatoriamente que seja consistente com o tamanho do servidor localmente aleatoriamente o RAF = new RandomAccessFile (nome do arquivo, "RWD"); System.out.println (FileLenth); // teste raf.setLength (comprimento do arquivo); // contagem de threads personalizada ThreadCount = 3; // Calcule o tamanho dos dados baixados por cada thread int blockSize = fileLength / ThreadCount; // Iniciar o encadeamento Download para (int threadId = 1; threadId <= ThreadCount; ThreadId ++) {// Código Core, defina o local de download no qual cada thread inicia e termina é int startPos = (ThreadId - 1) * Blocksize; // O local em que o download é o final do final (threadId * o último) - 1; = comprimento do arquivo; } new Thread (new DownloadLoadThread (ThreadId, StartPos, EndPos, Path)) .Start (); }} catch (Exceção e) {e.printStackTrace (); }} // Implementar o tópico de download da classe estática DownloadOrtHread implementa Runnable {private int threadId; Private int startpos; private int endpos; Caminho de cordas privadas; public DownloadLoadThread (int threadId, int startpos, int endpos, string path) {super (); this.ThreadId = ThreadID; this.startPos = startpos; this.endpos = endPos; this.Path = Path; } public void run () {try {url url = new url (caminho); String [] str = path.split ("/"); String filename = str [5]; HttpurlConnection Conn = (httpurlConnection) url .Openconnection (); // Defina o método da solicitação de URL (consulte a API para obter detalhes) Conn.SetRequestMethod ("Get"); // Defina 500ms como o valor do tempo limite Conn.SetReadTimeout (5000); Arquivo de arquivo = novo arquivo (threadId + ".txt"); if (file.exists () && file.length ()> 0) {buffarredReader Br = new BufferredReader (new InputStreamReader (new FileInputStream (File)); String SaveStartPos = Br.ReadLine (); if (SaveStartPos! = null && SaveStartPos.Length ()> 0) {startPos = Integer.parseint (SaveStartPos); }} // Preste atenção ao formato em cotações duplas e não pode conter espaços (como outros caracteres), caso contrário, 416 será relatada. Conn.SetRequestProperty ("Range", "Bytes =" + startpos + "-" + endpos); RafAccessFile RAF = novo RandomAccessFile (nome do arquivo, "rwd"); // armazenando o arquivo de gravação aleatório no arquivo de download raf.seek (startpos); // defina o local para iniciar o download system.out.println ("thread" + threadid + ":" + startpos + "~~" + endPOS); InputStream is = Conn.getInputStream (); byte [] b = novo byte [1024 * 1024 * 10]; int len = -1; int newpos = startPos; while ((len = is.read (b))! = -1) {RandomAccessFile rr = new RandomAccessFile (arquivo, "rwd"); // o arquivo que armazena o download tag raf.write (b, 0, len); // Salvar a tag de download na string de documentos especificada sdapoint = string.valueof (newpos += len); rr.Write (savaPoint.getBytes ()); rr.close (); } is.close (); raf.close (); System.out.println ("Download completo"); } catch (Exceção e) {e.printStackTrace (); }}}}Notas:
(1) Entenda o método de cálculo das posições iniciantes e finais de cada download do thread (sem incluir o último thread, comece a partir de 0)
Iniciar posição = (número de threads - 1) * O comprimento (tamanho) do arquivo a ser baixado por cada tópico
Posição final = (número de threads * tamanho do arquivo baixado por cada thread) -1
(2) A posição inicial do download atribuída pelo último thread é a posição final do thread anterior e a posição final é o comprimento do arquivo.
Portanto, o comprimento do arquivo baixado pelo último tópico geralmente não será o mesmo que o tópico anterior
(3) O caminho de download desta demonstração é o diretório em que o projeto Java está localizado por padrão, e o diretório não pode conter arquivos com o mesmo nome do arquivo baixado, caso contrário, o programa relatará um erro de solicitação de rede 416.
(4) um erro que cometi na implementação Conn.SetRequestProperty ("Range", "Bytes ="+startpos+"-"+endpos); Certifique -se de observar que as citações não têm necessariamente espaços extras e outros personagens. Eu só tenho um espaço nas citações, mas o posicionamento de erros sempre foi um erro de entrada e é muito doloroso encontrar os errados.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.