Java网络编程之单线程下载文件---多线程下载单个文件

一,单线程下载文件

下载文件的时候,如果为了用户友好,都会给予进度条提醒用户,那么怎么做呢?
其实很简单,首先获取服务器文件的大小
urlConnection.getContentLength(),然后在读取文件过程计算文件百分比增长即可

 
 
/**
 * 文件下载工具 by sam on 2018/7/30.
 */
public final class FileUtil {

    /**
     * 单线程下载文件
     * @param url 文件的网络地址
     * @param path 保存的文件地址
     */
    public static void dowanload(String url, String path)
            throws IOException {
        System.out.println("下载中...");
        InputStream inputStream = null;
        RandomAccessFile randomAccessFile = null;
        try {
            HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setConnectTimeout(10 * 1000);
            File file = new File(path);
            if (!file.getParentFile().exists())
                file.getParentFile().mkdir();
            if (file.exists())
                file.delete();
            file.createNewFile();
            int responseCode = urlConnection.getResponseCode();
            if (responseCode >= 200 && responseCode < 300) {
                inputStream = urlConnection.getInputStream();
                int len = 0;
                byte[] data = new byte[4096];
                int progres = 0; //用于保存当前进度(具体进度)
                int maxProgres = urlConnection.getContentLength();//获取文件
                randomAccessFile = new RandomAccessFile(file, "rwd");
                randomAccessFile.setLength(maxProgres);//设置文件大小
                int unit = maxProgres / 100;//将文件大小分成100分,每一分的大小为unit
                int unitProgress = 0; //用于保存当前进度(1~100%)
                while (-1 != (len = inputStream.read(data))) {
                    randomAccessFile.write(data, 0, len);
                    progres += len;//保存当前具体进度
                    int temp = progres / unit; //计算当前百分比进度
                    if (temp >= 1 && temp > unitProgress) {//如果下载过程出现百分比变化
                        unitProgress = temp;//保存当前百分比
                        System.out.println("正在下载中..." + unitProgress + "%");
                    }
                }
                inputStream.close();
                System.out.println("下载完成...");
            } else {
                System.out.println("服务器异常...");
            }
        } finally {
            if (null != inputStream) {
                inputStream.close();
            }
            if (null != randomAccessFile) {
                randomAccessFile.close();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        String path = "";//文件存放路径
        String url = "";//获取文件的路径地址
        FileUtil.dowanload(url, path);
    }
}

文章出处:https://blog.csdn.net/yoyo_newbie/article/details/49662135

二,多线程下载单个文件

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

/**
     实现思路:将文件分成 n块,每块用不同线程去下载,


 * 文件下载工具 by sam on 2018/07/30.
 */
public final class FileUtil {

    /**
     * 单线程下载文件
     *
     * @param url       文件的网络地址
     * @param path      保存的文件路径
     * @param threadNum 想要开启的线程数
     */
    public static void dowanload(String url, String path, int threadNum)
            throws IOException {
        System.out.println("下载中...");
        InputStream inputStream = null;
        RandomAccessFile randomAccessFile = null;
        try {
            HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setConnectTimeout(10 * 1000);
            File file = new File(path);
            if (!file.getParentFile().exists())
                file.getParentFile().mkdir();
            if (file.exists())
                file.delete();
            file.createNewFile();
            int responseCode = urlConnection.getResponseCode();
            if (responseCode >= 200 && responseCode < 300) {
                int fileSize = urlConnection.getContentLength();//获取文件大小
                randomAccessFile = new RandomAccessFile(file, "rwd");
                randomAccessFile.setLength(fileSize);//设置文件大小
                randomAccessFile.close();//设置文件大小后关闭

                //获取线程要处理的块数
                int value = fileSize % threadNum;
                int unit = fileSize/threadNum;//文件平均每块大小
                int block = 0 == value ? threadNum: threadNum + 1; //如果不整除,分多一块处理
                for (int i = 0; i < block; i++) {
                    int startMark = i * unit;//开始下载位置
                    int endMark = (i + 1) * unit - 1;//下载末端位置
                    DownloadFileThread thread = new DownloadFileThread(url, file, startMark, endMark);
                    thread.start();
                }

            } else {
                System.out.println("服务器异常...");
            }
        } finally {
            if (null != inputStream) {
                inputStream.close();
            }
            if (null != randomAccessFile) {
                randomAccessFile.close();
            }
        }
    }

    /***
     * 下载文件块线程
     */
    private static class DownloadFileThread extends Thread {
        private String url;
        private File file;
        private int startMark;
        private int endMark;

        public DownloadFileThread(String url, File file, int startMark, int endMark) {
            this.url = url;
            this.file = file;
            this.startMark = startMark;
            this.endMark = endMark;
        }


        @Override
        public void run() {
            InputStream inputStream = null;
            RandomAccessFile randomAccessFile = null;
            try {
                HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.setConnectTimeout(10 * 1000);
                //请求指定文件的位置,表明当前的一块获取的开始下载位置到末端位置
                urlConnection.setRequestProperty("Range", "bytes="+startMark+"-"+endMark);
                int responseCode = urlConnection.getResponseCode();
                if (responseCode >= 200 && responseCode < 300)
                {
                    inputStream = urlConnection.getInputStream();
                    int len = 0;
                    byte[] data = new byte[4096];
                    randomAccessFile = new RandomAccessFile(file, "rwd");
                    randomAccessFile.seek(startMark);//设置往文件写入部分
                    while (-1 != (len = inputStream.read(data))) {
                        randomAccessFile.write(data, 0, len);
                    }
                    System.out.println("下载完成..."+getName());
                }
                else
                {
                    System.out.println("服务器异常...");
                }
            } catch (Exception ex) {

            }
            finally {
                if (null != inputStream) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (null != randomAccessFile) {
                    try {
                        randomAccessFile.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }


    public static void main(String[] args) throws IOException {
        String path = "";
        String url = "";
        FileUtil.dowanload(url, path, 4);
    }
}

文章出处:https://blog.csdn.net/yoyo_newbie/article/details/49672211

猜你喜欢

转载自blog.csdn.net/weixin_42102798/article/details/81279116
今日推荐