一,单线程下载文件
下载文件的时候,如果为了用户友好,都会给予进度条提醒用户,那么怎么做呢?
其实很简单,首先获取服务器文件的大小
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