Este artigo descreve o download Java multi-thread. Compartilhe -o para sua referência, como segue:
O uso de arquivos multithread para baixar arquivos pode concluir o download de arquivos mais rapidamente. A razão pela qual os arquivos com vários threads são rápidos é que eles ocupam muitos recursos do servidor. Por exemplo: suponha que o servidor sirva até 100 usuários ao mesmo tempo, e um thread no servidor corresponde a um usuário. 100 threads não são executados simultaneamente no computador, mas são executados por sua vez pela CPU. Se o aplicativo A usa 99 threads para baixar arquivos, é equivalente a ocupar os recursos de 99 usuários. Suponha que o tempo médio de execução alocado pela CPU a cada encadeamento em um segundo seja de 10 mm. O aplicativo A obtém o tempo de execução de 990ms em um segundo no servidor, enquanto outros aplicativos têm apenas um tempo de execução de 10ms em um segundo. Assim como uma torneira, quando a produção de água por segundo é igual, é definitivamente mais água para 990 milissegundos do que por 10 milissegundos.
O processo de implementação do download multi-thread:
1. Primeiro, obtenha o comprimento do arquivo baixado e, em seguida, defina o comprimento do arquivo local.
HttpurlConnection.getContentLength (); RandomAccessFile File = new RandomAccessFile ("YouDao.exe", "rw"); file.setLength (fileSize); // Defina o comprimento do arquivo local2. Calcule o comprimento dos dados e baixe o local de cada thread com base no comprimento do arquivo e no número de threads. Por exemplo: o comprimento do arquivo é 6m e o número de threads é 3, o comprimento dos dados baixados por cada thread é 2m e o local onde cada thread inicia o download é mostrado na figura abaixo.
3. Use o campo de cabeçalho do alcance do HTTP para especificar de onde cada thread começa a baixar, como: Especifique o download do arquivo na posição 2M do arquivo, o código é o seguinte:
A cópia do código é a seguinte: httpurlconnection.setRequestProperty ("range", "bytes = 2097152-");
4. Salve o arquivo e use a classe RandomAccessFile para especificar de onde cada thread começa a gravar dados no arquivo local.
RandomAccessFile ThreadFile = new RandomAccessFile ("<span style =" font-family: Arial, Helvetica, Sans-Serif; "> Youdao.exe </span> <span style =" font-family: ARIAL, helvetica, sans-serf; o arquivoA seguir, a classe de implementação específica:
Antes de escrever a classe de implementação, devemos primeiro colocar o arquivo a ser baixado no servidor e implantar:
Coloquei aqui no diretório d: /tomcat/apache-tomcat-7.0.37/webapps/doudou e inicie o startup.bat sob d: /tomcat/apache-tomcat-7.0.37/bin
1.DownloadTest.java
pacote www.csdn.net.down; importar java.io.file; importar java.io.fileInputStream; importar java.io.fileOutputStream; importar java.io.ioException; importação java.io.inputStream; import.il.io.randomAcssfile importa; java.net.malformedurlexception; importar java.net.url; classe pública DownloadLoadTest {public File File; Public RandomAccessFile AccessFile; // número de threads public static int threadnum = 3; // Cada encadeamento é responsável por baixar o Int BlockSize; // Crie o caminho de acesso public string path = "http: // localhost: 8080/doudou/youdao.exe"; public static int threadCount; // Quantity public void testdown () {try {// crie url objeto url url = new url (caminho); // Crie objeto httpurlConnection httpurlConnection httpurlConnection = (httpurlConnection) url .openconnection (); // Defina o método de enviar solicitações httpurlconnection.setRequestMethod ("get"); // Defina se o tempo limite da solicitação httpurlConnection.setConnectTimeout (5000); // Definir httpurlConnection .SetRequestProperty ("User-Agent", "Mozilla/5.0 (compatível; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // se a resposta é bem -sucedida se (httpurlConnection.getRESPONSecode () == 200) {// obtenha o tamanho do arquivo int size = httpurlConnection.getContentLength (); System.out.println ("tamanho do arquivo" + tamanho); // Criar arquivo arquivo = novo arquivo ("youdao.exe"); AccessFile = new RandomAccessFile (arquivo, "RWD"); // defina o tamanho do arquivo accessfile.setLength (tamanho); // Baixe o tamanho de cada thread BlockSize = size / threadnum; // Abra três threads para operar esse arquivo para (int i = 1; i <= threadnum; i ++) {// 1 2 3 // calcule a posição inicial de cada thread int startize = (i - 1) * blocksize; // Posição final int Endsize = (i) * BlockSize; // Quando o thread é o último thread se (i == Threadnum) {// determine se o tamanho do arquivo é maior que a posição final calculada se (tamanho> Endsize) {// A posição final é igual ao tamanho do arquivo Enddize = size; }} // Crie uma leitura aleatória para cada thread RandomAccessFile ThreadAccessFile = new RandomAccessFile (arquivo, "RWD"); novo thread (novo downloadThread (i, threadaccessfile, startize, end Endize, caminho)). start (); }}} catch (malformedUrlexception e) {// TODO GATE GENERADO AUTOGERATO E.PRINTSTACKTRACE (); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); }} public static void main (string [] args) {DownloadTest DownloadTest = new DownloadTest (); // Ligue para o método de download DownloadTest.Testdown (); }} classe DownloadOlLoadThread implementa Runnable {// encapsulamento do arquivo de download public RandomAccessFile AccessFile; // Cada encadeamento possui um arquivo de arquivo de acesso thread1 thread2 thread3 // a posição inicial do arquivo de thread download public int startize; public Int end Endize; // O caminho do caminho do arquivo Download public String Path; public int threadid; // A identificação do thread public DownloadThread (int threadId, RandomAccessFile AccessFile, int startize, int Endize, String Path) {this.ThreadId = ThreadId; this.accessfile = AccessFile; this.startsize = startize; this.endsize = endsize; this.Path = Path; } @Override public void run () {// Execute o método de execução tente {// crie um arquivo file threadfile = new arquivo (threadId + ".txt"); if (threadfile.exists ()) {// Leia o conteúdo do arquivo // Crie o objeto de fluxo de entrada do arquivo FileInputStream fis = new FileInputStream (ThreadFile); // Use a classe de ferramenta para ler dados de bytes [] = streamtools.istodata (fis); // converte para string string threadlen = new string (dados); if ((threadlen! = null) && (! "". Equals (threadlen))) {startize = intoger.valueof (shreadlen); // Resolva o erro de 416bug if (startize> endsize) {startize = endsize - 1; }}} // Crie url objeto url = new url (caminho); // Crie objeto httpurlConnection httpurlConnection httpurlConnection = (httpurlConnection) url .openconnection (); // defina o cabeçalho da solicitação httpurlconnection.setRequestMethod ("get"); // Defina se o tempo limite da solicitação httpurlConnection.setConnectTimeout (5000); // Definir httpurlConnection .SetRequestProperty ("User-Agent", "Mozilla/5.0 (compatível; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // As configurações de chave httpurlconnection.setRequestProperty ("range", "bytes =" + startize + "-" + endsize); // em saída o sistema de encadeamento atual.out.println ("thread atual" + threadId + "Download de inicialização:" + startize + "Download Posição final:" + Endsize); // Resposta bem -sucedida // Defina a posição inicial dos arquivos de leitura aleatória accessfile.seek (startize); // obtenha o objeto de fluxo correspondente inputStream is = httpurlConnection.getInputStream (); // cria buffer de objeto de fluxo de fluxo de saída [] = novo byte [1024]; int len = 0; int threadTotal = 0; // Salvar registro depois que cada thread for baixado/ while (len = is.read (buffer))! = -1) {accessfile.write (buffer, 0, len); ThreadTotal += len; // grava o comprimento que você escreve // xml file // grava o comprimento do arquivo de arquivo através do arquivo FileOutputStream fos = new FileOutputStream (ThreadFile); fos.Write ((ThreadTotal + "") .GetBytes ()); fos.flush (); fos.close (); } AccessFile.Close (); is.close (); System.out.println (ThreadId + "Execução do thread é concluída"); // Operação do thread Sincronized (DownloadTest.class) {DownloadLoadTest.ThreadCount ++; if (DownloadTest.ThreadCount> = DownloadLoadTest.ThreadNum) {for (int i = 1; i <= downloadTest.threadnum; i ++) {arquivo file = new File (i+". txt"); if (file.exists ()) {file.delete (); }}}}} catch (malformEdUrlexception e) {// TODO BLOCO DE CATAGEM AUTOGERATION E.PRINTSTACKTRACE (); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); }}}2.
pacote www.csdn.net.down; importar java.io.bytearrayoutputStream; importar java.io.ioexception; importar java.io.inputStream; public class Streamtools {public static bytear [] istodata (inputStream) throws ioxception { / byteararearear [] istodata (inputStream)) // A área de buffer para leitura de dados byte buffer [] = novo byte [1024]; // LEIA LEND LIMPE RECORD INT LEN = 0; // Leitura de loop while ((len = is.read (buffer))! = -1) {bops.write (buffer, 0, len); } // Converta o conteúdo de leitura em uma matriz de bytes dados de bytes [] = bops.tobytearray (); bops.flush (); bops.close (); is.close (); retornar dados; }}Espero que este artigo seja útil para a programação Java de todos.