Java内存映射文件实现多线程下载


Java NIO内存映射文件可以实现多线程下载

首先,使用Firefox下载一个Tomcat

Java多线程:一道阿里面试题的分析与应对

Java多线程下载程序

import java.io.FileNotFoundException;
 
import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

import java.nio.MappedByteBuffer;

import java.nio.channels.FileChannel.MapMode;

 

class Worker implements Runnable {

    //多线程下载的数量

    private static int THREADS = 4;

    //每个线程下载开始的位置

    private int startIndex;

    //每个线程下载内容的长度

    private int length;

    //文件保存位置

    private String localFile;

    //远程文件的流

    InputStream in;

 

    private Worker(String urlFile, String localFile, int startIndex, int length) throws IOException {

        this.startIndex = startIndex;

        this.length = length;

        this.localFile = localFile;

        init(urlFile);

    }

 

    /**

    *    主线程打开网络文件,先分割为指定的大小,然后开启多线程下载

    */

    public Worker(String urlFile, String localFile) throws IOException {

        this.localFile = localFile;

        int contentLength = init(urlFile);

        int step = contentLength / THREADS;

        int index = 0;

        for (int i = 0; i < THREADS; i++) {

            if (i == 0) {

                this.startIndex = 0;

                this.length = step;

                new Thread(this).start();

            } else if (i == THREADS - 1) {

                Worker worker = new Worker(urlFile, localFile, index, contentLength - index);

                new Thread(worker).start();

            } else {

                Worker worker = new Worker(urlFile, localFile, index, step);

                new Thread(worker).start();

            }

            index = index + step;

        }

    }

 

    private int init(String urlFile) throws IOException {

        URL url;

 

        url = new URL(urlFile);

 

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

 

        connection.setConnectTimeout(5 * 1000);

        connection.setRequestMethod("GET");

        connection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " + "application/x-shockwave-flash, application/xaml+xml, "

                + "application/vnd.ms-xpsdocument, application/x-ms-xbap, " + "application/x-ms-application, application/vnd.ms-excel, " + "application/vnd.ms-powerpoint, application/msword, */*");

        connection.setRequestProperty("Accept-Language", "zh-CN");

        connection.setRequestProperty("Charset", "UTF-8");

        connection.setRequestProperty("Connection", "Keep-Alive");

        InputStream in = connection.getInputStream();

        this.in = in;

        return connection.getContentLength();

    }

 

    @Override

    public void run() {

        System.out.println(this);

        try {

            RandomAccessFile localRandomFile = new RandomAccessFile(localFile, "rw");

            MappedByteBuffer buffer = localRandomFile.getChannel().map(MapMode.READ_WRITE, startIndex, length);

            int i = 0;

            in.skip(startIndex);

            while (i < length) {

                buffer.put((byte) in.read());

                i++;

            }

            buffer.force();

            in.close();

            localRandomFile.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

 

    @Override

    public String toString() {

        return "Worker [localFile=" + localFile + ", startIndex=" + startIndex + ", length=" + length + "]";

    }

 

    public static void main(String[] args) throws IOException {

        new Worker("http://mirrors.cnnic.cn/apache/tomcat/tomcat-7/v7.0.53/bin/apache-tomcat-7.0.53.zip", "tomcat.zip");

    }

}

比对下载的文件
 

Java1.5后的多线程框架

Java多线程和同步的理解

Java中两种实现多线程方式的对比分析

Java利用多线程计算目录数据大小

Java多线程向数据库写入数据

本文永久更新链接地址:

相关内容

    暂无相关文章