代码:


import io.github.viscent.mtia.util.Debug;
import io.github.viscent.mtia.util.Tools;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;public class FileDownloaderApp {public static void main(String[] args) {String[]pics =new String[]{"https://dlqn.aoscdn.com/beecut-setup-pin.exe","https://scpic.chinaz.net/files/pic/pic9/202112/apic37306.jpg"};Thread downloaderThread = null;for (String url : pics) {// 创建文件下载器线程downloaderThread = new Thread(new FileDownloader(url));// 启动文件下载器线程downloaderThread.start();}}// 文件下载器线程类,拓展runnable接口static class FileDownloader implements Runnable {private final String fileURL;public FileDownloader(String fileURL) {this.fileURL = fileURL;}
//在run方法中获取文件夹路径,调用下载文件的方法进行下载@Overridepublic void run() {Debug.info("Downloading from " + fileURL);String fileBaseName = fileURL.substring(fileURL.lastIndexOf('/') + 1);try {URL url = new URL(fileURL);String localFileName = System.getProperty("java.io.tmpdir")//自己电脑系统的临时文件夹路径位置+ fileBaseName;Debug.info("Saving to: " + localFileName);downloadFile(url, new FileOutputStream(localFileName), 1024);} catch (Exception e) {e.printStackTrace();}Debug.info("Done downloading from " + fileURL);}// 从指定的URL下载文件,并将其保存到指定的输出流中,在这里使用了nio的 ReadableByteChannel和WritableByteChannel    用方法 buf.flip();
// outChannel.write(buf);从给定的缓冲区将字节序列写入此通道private void downloadFile(URL url, OutputStream outputStream, int bufSize)throws MalformedURLException, IOException {// 建立HTTP连接final HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();httpConn.setRequestMethod("GET");ReadableByteChannel inChannel = null;WritableByteChannel outChannel = null;try {// 获取HTTP响应码int responseCode = httpConn.getResponseCode();// HTTP响应非正常:响应码不为2开头if (2 != responseCode / 100) {throw new IOException("Error: HTTP " + responseCode);}if (0 == httpConn.getContentLength()) {Debug.info("Nothing to be downloaded " + fileURL);return;}inChannel = Channels.newChannel(new BufferedInputStream(httpConn.getInputStream()));outChannel = Channels.newChannel(new BufferedOutputStream(outputStream));ByteBuffer buf = ByteBuffer.allocate(bufSize);while (-1 != inChannel.read(buf)) {buf.flip();outChannel.write(buf);buf.clear();}} finally {// 关闭指定的Channel以及HttpURLConnectionTools.silentClose(inChannel, outChannel);httpConn.disconnect();}}// downloadFile结束}// FileDownloader结束
}

其中Debug为自定义的工具类


import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;public class Debug {private static ThreadLocal<SimpleDateFormat> sdfWrapper = new ThreadLocal<SimpleDateFormat>() {@Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");}};enum Label {INFO("INFO"),ERR("ERROR");String name;Label(String name) {this.name = name;}public String getName() {return name;}}// public static void info(String message) {// printf(Label.INFO, "%s", message);// }public static void info(String format, Object... args) {printf(Label.INFO, format, args);}public static void info(boolean message) {info("%s", message);}public static void info(int message) {info("%d", message);}public static void error(String message, Object... args) {printf(Label.ERR, message, args);}public static void printf(Label label, String format, Object... args) {SimpleDateFormat sdf = sdfWrapper.get();@SuppressWarnings("resource")final PrintStream ps = label == Label.INFO ? System.out : System.err;ps.printf('[' + sdf.format(new Date()) + "][" + label.getName()+ "]["+ Thread.currentThread().getName() + "]:" + format + " %n", args);}
}

其中tools关闭文件的方法:


public final class Tools {private static final Random rnd = new Random();private static final Logger LOGGER = Logger.getAnonymousLogger();public static void startAndWaitTerminated(Thread... threads)throws InterruptedException {if (null == threads) {throw new IllegalArgumentException("threads is null!");}for (Thread t : threads) {t.start();}for (Thread t : threads) {t.join();}}public static void startAndWaitTerminated(Iterable<Thread> threads)throws InterruptedException {if (null == threads) {throw new IllegalArgumentException("threads is null!");}for (Thread t : threads) {t.start();}for (Thread t : threads) {t.join();}}public static void randomPause(int maxPauseTime) {int sleepTime = rnd.nextInt(maxPauseTime);try {Thread.sleep(sleepTime);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}public static void randomPause(int maxPauseTime, int minPauseTime) {int sleepTime = maxPauseTime == minPauseTime ? minPauseTime : rnd.nextInt(maxPauseTime - minPauseTime) + minPauseTime;try {Thread.sleep(sleepTime);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}public static void silentClose(Closeable... closeable) {if (null == closeable) {return;}for (Closeable c : closeable) {if (null == c) {continue;}try {c.close();} catch (Exception ignored) {}}}public static void split(String str, String[] result, char delimeter) {int partsCount = result.length;int posOfDelimeter;int fromIndex = 0;String recordField;int i = 0;while (i < partsCount) {posOfDelimeter = str.indexOf(delimeter, fromIndex);if (-1 == posOfDelimeter) {recordField = str.substring(fromIndex);result[i] = recordField;break;}recordField = str.substring(fromIndex, posOfDelimeter);result[i] = recordField;i++;fromIndex = posOfDelimeter + 1;}}public static void log(String message) {LOGGER.log(Level.INFO, message);}public static String md5sum(final InputStream in) throws NoSuchAlgorithmException, IOException {MessageDigest md = MessageDigest.getInstance("MD5");byte[] buf = new byte[1024];try (DigestInputStream dis = new DigestInputStream(in, md)) {while (-1 != dis.read(buf)){};}byte[] digest = md.digest();BigInteger bigInt = new BigInteger(1, digest);String checkSum = bigInt.toString(16);while (checkSum.length() < 32) {checkSum = "0" + checkSum;}return checkSum;}public static String md5sum(final File file) throws NoSuchAlgorithmException, IOException {return md5sum(new BufferedInputStream(new FileInputStream(file)));}public static void delayedAction(String prompt, Runnable action, int delay/* seconds */) {Debug.info("%s in %d seconds.", prompt, delay);try {Thread.sleep(delay * 1000);} catch (InterruptedException ignored) {}action.run();}public static Object newInstanceOf(String className) throws InstantiationException,IllegalAccessException, ClassNotFoundException {return Class.forName(className).newInstance();}}

结果:
可以看到这里开了两个线程用于下载上面的两个链接

文件夹下面可以看到刚刚自己下载好的两个文件:

打开图片也可以看到完整的图片显示:

使用nio多线程下载网络文件实例相关推荐

  1. [工具库]JFileDownloader工具类——多线程下载网络文件,并保存在本地

    本人大四即将毕业的准程序员(JavaSE.JavaEE.android等)一枚,小项目也做过一点,于是乎一时兴起就写了一些工具. 我会在本博客中陆续发布一些平时可能会用到的工具. 代码质量可能不是很好 ...

  2. java下载网络文件_java下载网络文件的方法有哪些

    下载网络文件的方法有:字节流下载 apache的FileUtils工具包下载 NIO下载 实现代码如下:package com.dsp.rpc.metricelf; import org.apache ...

  3. AsyncTask下载网络文件,并显示下载进度

    一些说明 ProgressBar.setProgress(): 刷新UI操作必须运行在UI线程中,但是setProgress()方法里面已经做了同步操作,所以可以在非UI线程中调用 webView.l ...

  4. 【C#】【HttpClient】下载网络文件

    通过 HttpClient 下载网络文件 前言:之前有需求从某个网站自动下载其文件.而事先我是没有这方面的开发经验的.找了许多资料大多是采用 WebClient 类进行网络文件的获取.然而我去 MSD ...

  5. [Python]_[初级]_[多线程下载单个文件]

    场景 使用Python做自动化测试时,有时候需要从网络下载软件安装包并安装.但是使用urllib库时,默认都是单线程下载文件,如果文件比较小还好说,如果文件有20M时,普通的网速就要等待很长的时间.有 ...

  6. java下载网络文件的N种方式

    通过java api下载网络文件的方法有很多,在这里我做个汇总,主要方式有以下几种: 1.使用 common-io库下载文件,需要引入commons-io-2.6.jar public static ...

  7. wget命令——下载网络文件

    wget命令是英文词组"web get"的缩写,用于从指定网址下载网络文件. wget命令支持如HTTP.HTTPS.FTP等常见协议,可以在命令行中直接下载网络文件. 与curl ...

  8. python 小说下载_Python下载网络小说实例代码

    看网络小说一般会攒上一波,然后导入Kindle里面去看,但是攒的多了,机械的Ctrl+C和Ctrl+V实在是OUT,所以就出现了此文. 其实Python我也是小白,用它的目的主要是它强大文本处理能力和 ...

  9. Java8环境下使用restTemplate单/多线程下载大文件和小文件

    Java8环境下使用restTemplate单/多线程下载大文件和小文件 0. 准备工作 1. 简单的下载文件 2. 单线程大文件下载 3. 多线程下载 0. 准备工作 下面使用的restTempla ...

最新文章

  1. vue+webpack+amazeui项目小记
  2. 从.NET和Java之争谈IT这个行业
  3. java检测tcp存活_keep-alive 和 TCP存活检测
  4. java sftp 实例_JAVA实现SFTP的实例
  5. jni c 回调 java,JNI - 如何从C ++或C回调到Java?
  6. 语音识别哪家强?百度 、苹果、科大讯飞都有制胜法宝
  7. iOS 关于TouchID指纹解锁的实现
  8. java-jna win32 api使用
  9. xshell5产品秘钥
  10. JAVA中计算五子棋平局的算法_五子棋计算思路
  11. 三菱PLC排故障的方法
  12. 即时通信软件实现原理
  13. 谷歌工程师深度技术分析“为什么ios比android流畅
  14. Edge 被 hao123 劫持解决方法
  15. Greedy search 和 beam search
  16. Elasticsearch 分布式搜索引擎 -- 自动补全(拼音分词器、自定义分词器、自动补全查询、实现搜索框自动补全)
  17. 仓库防霉防潮作业指导书
  18. matlab中怎么贮存函数,MATLAB参数保存、调用
  19. PDF转成JPG,使用PDFTOJPG并去除水印
  20. facenet 人脸识别库的搭建和使用方法(二)

热门文章

  1. 优酷ts转换mp4_如何方便快捷无损地下载腾讯视频 (mp4格式)
  2. 壳体有矩理论与实用计算机方法,《薄壳计算和理论》.pdf
  3. 游戏使用html签名,关于玩游戏的个性签名
  4. 语法制导的三地址代码生成程序_ts-creator, 一个生成代码生成器的代码生成器
  5. 标定中是什么意思_机械加工中,测头有什么作用呢?
  6. 计算机网络与影视多媒体技术 南京理工大学,计算机网络多媒体数学库和课件结构设计-计算机仿真论文-计算机论文(8页)-原创力文档...
  7. php如何替换 前的空格,php空格如何替换
  8. 如何linux中文改为英文,CentOS系统如何将中文语言改成英文
  9. 查询jsp servelet mysql_JSP + Servlet + JDBC + Mysql 实现增删改查 课程管理系统(示例代码)...
  10. 为了OFFER,我加深学习,搞懂了栈