当前位置:   article > 正文

Java利用URL实现文件下载_java 通过文件url下载文件放入token

java 通过文件url下载文件放入token

利用URL(网络资源统一定位符),我们可以进行文件的定位和下载,

如果我们想让下载速度提高一些,我们通常有以下方法:

1.提高网络带宽,提升网络速度

2.开通网站vip,实现高速下载或上传

3.新增下载线程,实现多线程同时下载

通常情况下,方法1是作为一个普通程序员是无法实现的,因为网络带宽是由网络运行商限定,

除非我们多交钱或者是开通专用通道(vpn),

方法2的话,也是需要花钱,比如某云盘,只要你充值会员,就可以实现高速下载或是上传文件,

其实,我说那么多都是废话,我想分享给大家的就是方法3,利用URL进行多线程下载,

由于代码注释我都写的很明了,所有直接上代码了,下面就是主类代码,不需引入三方jar包,可直接运行,

运行该类可以从hao123网站下载一个输入法,当然了,URL地址可以随便更改。

  1. package com.yc.net;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.net.URL;
  8. import java.net.URLConnection;
  9. import java.util.Date;
  10. /**
  11. * 多线程下载
  12. *
  13. * @author jam
  14. *
  15. */
  16. public class ThreadDownloader {
  17. public static void main(String[] args) throws IOException, InterruptedException {
  18. // 记录开始下载的时间
  19. long begin_time = new Date().getTime();
  20. // 创建一个URL链接
  21. // 从hao123网站下载一个输入法,下面是下载地址
  22. URL url = new URL("http://softdown1.hao123.com/hao123-soft-online-bcs/soft/2017_09_29_jpwb2017qj.exe");
  23. // 获取连接
  24. URLConnection conn = url.openConnection();
  25. // 获取文件全路径
  26. String fileName = url.getFile();
  27. // 获取文件名
  28. fileName = fileName.substring(fileName.lastIndexOf("/"));
  29. System.out.println("开始下载>>>");
  30. // 获取文件大小
  31. int fileSize = conn.getContentLength();
  32. System.out.println("文件总共大小:" + fileSize + "字节");
  33. // 设置分块大小
  34. int blockSize = 1024 * 1024;
  35. // 文件分块的数量
  36. int blockNum = fileSize / blockSize;
  37. if ((fileSize % blockSize) != 0) {
  38. blockNum += 1;
  39. }
  40. System.out.println("分块数->线程数:" + blockNum);
  41. Thread[] threads = new Thread[blockNum];
  42. for (int i = 0; i < blockNum; i++) {
  43. // 匿名函数对象需要用到的变量
  44. final int index = i;
  45. final int finalBlockNum = blockNum;
  46. final String finalFileName = fileName;
  47. // 创建一个线程
  48. threads[i] = new Thread() {
  49. public void run() {
  50. try {
  51. // 重新获取连接
  52. URLConnection conn = url.openConnection();
  53. // 重新获取流
  54. InputStream in = conn.getInputStream();
  55. // 定义起始和结束点
  56. int beginPoint = 0, endPoint = 0;
  57. System.out.print("第" + (index + 1) + "块文件:");
  58. beginPoint = index * blockSize;
  59. // 判断结束点
  60. if (index < finalBlockNum - 1) {
  61. endPoint = beginPoint + blockSize;
  62. } else {
  63. endPoint = fileSize;
  64. }
  65. System.out.println("起始字节数:" + beginPoint + ",结束字节数:" + endPoint);
  66. // 将下载的文件存储到一个文件夹中
  67. //当该文件夹不存在时,则新建
  68. File filePath = new File("E:/temp_file/");
  69. if (!filePath.exists()) {
  70. filePath.mkdirs();
  71. }
  72. FileOutputStream fos = new FileOutputStream(new File("E:/temp_file/", finalFileName + "_" + (index + 1)));
  73. // 跳过 beginPoint个字节进行读取
  74. in.skip(beginPoint);
  75. byte[] buffer = new byte[1024];
  76. int count;
  77. // 定义当前下载进度
  78. int process = beginPoint;
  79. // 当前进度必须小于结束字节数
  80. while (process < endPoint) {
  81. count = in.read(buffer);
  82. // 判断是否读到最后一块
  83. if (process + count >= endPoint) {
  84. count = endPoint - process;
  85. process = endPoint;
  86. } else {
  87. // 计算当前进度
  88. process += count;
  89. }
  90. // 保存文件流
  91. fos.write(buffer, 0, count);
  92. }
  93. fos.close();
  94. in.close();
  95. } catch (Exception e) {
  96. e.printStackTrace();
  97. }
  98. }
  99. };
  100. threads[i].start();
  101. }
  102. // 当所有线程都结束时才开始文件的合并
  103. for (Thread t : threads) {
  104. t.join();
  105. }
  106. // 若该文件夹不存在,则创建一个文件夹
  107. File filePath = new File("E:/download/");
  108. if (!filePath.exists()) {
  109. filePath.mkdirs();
  110. }
  111. // 定义文件输出流
  112. FileOutputStream fos = new FileOutputStream("E:/download/" + fileName);
  113. for (int i = 0; i < blockNum; i++) {
  114. FileInputStream fis = new FileInputStream("E:/temp_file/" + fileName + "_" + (i + 1));
  115. byte[] buffer = new byte[1024];
  116. int count;
  117. while ((count = fis.read(buffer)) > 0) {
  118. fos.write(buffer, 0, count);
  119. }
  120. fis.close();
  121. }
  122. fos.close();
  123. long end_time = new Date().getTime();
  124. long seconds = (end_time - begin_time) / 1000;
  125. long minutes = seconds / 60;
  126. long second = seconds % 60;
  127. System.out.println("下载完成,用时:" + minutes + "分" + second + "秒");
  128. }
  129. }

 

该类利用了多线程进行文件的下载,等到每个线程都下载完成后,我们将每个线程下载好的文件合并为一个完整的文件。

可以看到,三个线程同时进行下载,下图展示了临时文件的存储情况:

程序成功运行完后,控制台输出情况如下:

当所有的线程都下载好了临时文件后,程序会将这些临时文件合并为一个完整的文件:

这个时候,我们可以看到一个完整的文件已经下载到了我们指定的文件夹中了,这样,我们利用URL进行多线程下载就成功了。

该文章只是作为我学习URL和多线程的笔记,刚入门的童鞋可以参考一下,如有错误,欢迎指正。

文章属原创,如需引用,请注明出处,谢谢。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/55423
推荐阅读
相关标签
  

闽ICP备14008679号