使用HttpURLConnection下载文件时经常会出现 java.io.FileNotFoundException文件找不到异常,下面介绍下解决办法

首先设置tomcat对get数据的编码:conf/server.xml

  1. <Connector port="8080" protocol="HTTP/1.1"
  2. connectionTimeout="20000"
  3. redirectPort="8443"
  4. <span style="color:#ff0000;"> URIEncoding="UTF-8"</span> />

其次对请求的文件名进行编码:

  1. import java.io.File;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.RandomAccessFile;
  5. import java.net.HttpURLConnection;
  6. import java.net.URL;
  7. import java.net.URLEncoder;
  8. /**
  9. * 多线程下载
  10. * @author bing
  11. *
  12. */
  13. public class OmbDownloadOfThreadsUtil {
  14. private String urlPath ; // 资源网络路径
  15. private String targetFilePath ; // 所下载文件的保存路径
  16. private int threadNum ; // 启用多少条线程进行下载
  17. // 用于下载线程对象集合
  18. private DownloadThread[] downloadThreads ;
  19. // 要下载文件的大小
  20. private int fileSize ;
  21. public OmbDownloadOfThreadsUtil(String urlPath, String targetFilePath,
  22. int threadNum) {
  23. this.urlPath = urlPath;
  24. this.targetFilePath = targetFilePath;
  25. this.threadNum = threadNum;
  26. downloadThreads = new DownloadThread[threadNum] ;
  27. }
  28. public void downloadFile() throws Exception{
  29. URL url = new URL(urlPath) ;
  30. HttpURLConnection conn = (HttpURLConnection) url.openConnection() ;
  31. conn.setConnectTimeout(4*1000) ;
  32. conn.setRequestMethod("GET") ;
  33. conn.setRequestProperty(
  34. "Accept",
  35. "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
  36. "application/x-shockwave-flash, application/xaml+xml, " +
  37. "application/vnd.ms-xpsdocument, application/x-ms-xbap, " +
  38. "application/x-ms-application, application/vnd.ms-excel, " +
  39. "application/vnd.ms-powerpoint, application/msword, */*");
  40. conn.setRequestProperty("Accept-Language", "zh-CN");
  41. conn.setRequestProperty("Charset", "UTF-8");
  42. //设置浏览器类型和版本、操作系统,使用语言等信息
  43. conn.setRequestProperty(
  44. "User-Agent",
  45. "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/4.0; " +
  46. ".NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; " +
  47. ".NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
  48. //设置为长连接
  49. conn.setRequestProperty("Connection", "Keep-Alive");
  50. //得到要下载文件的大小
  51. fileSize = conn.getContentLength() ;
  52. System.out.println("fileSize:"+fileSize);
  53. //断开连接
  54. conn.disconnect() ;
  55. //计算每条线程需要下载的大小
  56. int preThreadDownloadSize = fileSize/threadNum+1 ;
  57. System.out.println("preThreadDownloadSize:"+preThreadDownloadSize);
  58. RandomAccessFile file = new RandomAccessFile(targetFilePath, "rw") ;
  59. file.setLength(fileSize) ;
  60. file.close() ;
  61. for (int i = 0; i < threadNum; i++) {
  62. // 计算每条线程下载的起始位置
  63. int startPos = i*preThreadDownloadSize+1 ;
  64. RandomAccessFile currentPart = new RandomAccessFile(targetFilePath, "rw") ;
  65. currentPart.seek(startPos) ;
  66. downloadThreads[i] = new DownloadThread(startPos,preThreadDownloadSize,currentPart) ;
  67. new Thread(downloadThreads[i]).start() ;
  68. }
  69. }
  70. /**
  71. * 获取下载的完成百分比
  72. * @return 完成的百分比
  73. */
  74. public double getCompleteRate() {
  75. // 统计多条线程已经下载的总大小
  76. int sumSize = 0;
  77. for (int i = 0; i < threadNum; i++) {
  78. sumSize += downloadThreads[i].hasReadLength;
  79. }
  80. // 返回已经完成的百分比
  81. return sumSize * 1.0 / fileSize;
  82. }
  83. /**
  84. * 用于下载的线程
  85. * @author bing
  86. *
  87. */
  88. private final class DownloadThread implements Runnable{
  89. private int startPos ;
  90. private int preThreadDownloadSize ;
  91. private RandomAccessFile currentPart ;
  92. //已下载长度
  93. private int hasReadLength ;
  94. public DownloadThread(int startPos, int preThreadDownloadSize,
  95. RandomAccessFile currentPart) {
  96. this.startPos = startPos;
  97. this.preThreadDownloadSize = preThreadDownloadSize;
  98. this.currentPart = currentPart;
  99. }
  100. @Override
  101. public void run() {
  102. InputStream inputStream = null ;
  103. try{
  104. URL url = new URL(urlPath) ;
  105. HttpURLConnection conn = (HttpURLConnection) url.openConnection() ;
  106. conn.setConnectTimeout(4*1000) ;
  107. conn.setRequestMethod("GET") ;
  108. conn.setRequestProperty(
  109. "Accept",
  110. "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
  111. "application/x-shockwave-flash, application/xaml+xml, " +
  112. "application/vnd.ms-xpsdocument, application/x-ms-xbap, " +
  113. "application/x-ms-application, application/vnd.ms-excel, " +
  114. "application/vnd.ms-powerpoint, application/msword, */*");
  115. conn.setRequestProperty("Accept-Language", "zh-CN");
  116. conn.setRequestProperty("Charset", "UTF-8");
  117. inputStream = conn.getInputStream() ;
  118. inputStream.skip(startPos) ;//定位到开始位置
  119. byte[] buffer = new byte[1024] ;
  120. int temp = 0 ;
  121. while(hasReadLength<preThreadDownloadSize
  122. &&(temp=inputStream.read(buffer))!=-1){
  123. currentPart.write(buffer,0,temp) ;
  124. hasReadLength += temp ;
  125. }
  126. }catch(Exception e){
  127. e.printStackTrace() ;
  128. }finally{
  129. try {
  130. currentPart.close() ;
  131. } catch (Exception e) {
  132. e.printStackTrace();
  133. }
  134. try {
  135. inputStream.close() ;
  136. } catch (Exception e) {
  137. e.printStackTrace();
  138. }
  139. }
  140. }
  141. }
  142. public static void main(String[] args) throws Exception {
  143. String songName = "许嵩 - 半城烟沙.mp3" ;
  144. songName = URLEncoder.encode(songName,"UTF-8") ;
  145. String urlPath = "http://172.16.2.50:8080/mp3/"+songName ;
  146. String targetDir = "E:"+File.separator+songName ;
  147. OmbDownloadOfThreadsUtil odtu = new OmbDownloadOfThreadsUtil(urlPath,targetDir, 6) ;
  148. odtu.downloadFile() ;
  149. }
  150. }

经过以上三步基本上问题已经解决,但如果的文件名含有空格的话还需一步:

URLs是不能包含空格的。URL encoding一般会使用“+”号去替换空格,但后台服务器(我的是Tomcat6.0)又不能把“+”还原为空格,所以导致文件找不到,解决办法:只需把“+”替换为“%20”

    1. public static void main(String[] args) throws Exception {
    2. String songName = "许嵩 - 半城烟沙.mp3" ;
    3. songName = URLEncoder.encode(songName,"UTF-8").replace("+", "%20") ;
    4. String urlPath = "http://172.16.2.50:8080/mp3/"+songName ;
    5. String targetDir = "E:"+File.separator+songName ;
    6. OmbDownloadOfThreadsUtil odtu = new OmbDownloadOfThreadsUtil(urlPath,targetDir, 6) ;
    7. odtu.downloadFile() ;
    8. }

使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法的更多相关文章

  1. MS SQL执行大脚本文件时,提示“内存不足”的解决办法()

    问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当数据库导出脚本很大,用Microsoft SQL Server Management Studio执行 ...

  2. MS SQL2008执行大脚本文件时,提示“内存不足”的解决办法

    问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当数据库导出脚本很大,用Microsoft SQL Server Management Studio执行 ...

  3. MSSQL执行大脚本文件时,提示“内存不足”的解决办法

    导出了一个脚本文件,将近900M,回来往sql studio一丢,报了个内存不足,然后就有了此文.. 问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当 ...

  4. SQL SERVER 2008R2 执行大脚本文件时,提示“内存不足”的解决办法

    我把一个数据库的架构及数据都已脚本的方式拷贝下来,再去新建一个数据库想把脚本执行一下,但提示如下错误: 问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是 ...

  5. 使用Android SDK Manager下载sdk时总是出现中断异常的解决办法。

    1.搜到到你本机的hosts文件. 2.打开该文件. 3.在该文件最后一行添加:74.125.31.136 dl-ssl.google.com 4.重新下载问题解决. 参考链接:http://bbs. ...

  6. 关于在工程中添加新文件时的LNK2019错误的一个解决办法

    我这几天一直在研究Qt的串口程序,在读懂了官方给出的实例程序后我决定把其多线程的串口监视程序加入到我自己的工程中,便直接把问价复制到自己的工程下面,在Qt中加入到自己的工程中,但是总是出现LNK201 ...

  7. flask上传文件时request.files为空的解决办法

    在做上传文件的时候遇到request.files是空 原因在于html中的表单form没有指明 enctype="multipart/form-data" <form met ...

  8. GraphicsMagick java.io.FileNotFoundException: gm 错误解决办法

    GraphicsMagick java.io.FileNotFoundException: gm 解决办法, 方法一: ProcessStarter.setGlobalSearchPath(" ...

  9. Android下载文件提示文件不存在。。。 java.io.FileNotFoundException

    遇到这个错误java.io.FileNotFoundException,事实上文件是存在的,把地址复制到手机浏览器都能够直接下载的,但为嘛不能下载呢. Error in downloadBitmap ...

随机推荐

  1. 暑假集训单切赛第一场 CF 266E More Queries to Array(线段树+二项式展开式)

    比赛时,第二题就是做的这个,当时果断没仔细考虑,直接用线段树暴力求.结果易想而知,超时了. 比赛后搜了搜题解,恍然大悟. 思路:显然用线段树,但是由于每次查询都会有变,所以不可能存储题目中的式子.   ...

  2. APT工作原理

    两篇好的文章:http://blog.csdn.net/newjueqi/article/details/6679857 http://blog.csdn.net/buguyiqie/article/ ...

  3. hdu 1002 java 大数相加

    package Main; //import java.io.InputStream; import java.math.BigDecimal; import java.util.Scanner; p ...

  4. php规范

    PSR-0 自动加载 PSR-1 基本代码规范 PSR-2 代码样式 PSR-3 日志接口

  5. seafile安装日志(非教程)

    需要的软件: python 2.7.x(从 Seafile 5.1 开始,python 版本最低要求为2.7) python-setuptools python-imaging python-mysq ...

  6. 57. Insert Interval

    题目: Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if nec ...

  7. NOT EXISTS优化的一个案例 .

    原始语句: SELECT * FROM dcf_account.t_posting_transaction t1 WHERE NOT EXISTS ( SELECT * FROM dcf_loan.t ...

  8. NDK 提示"undefined reference to xxx“的解决办法

    在Android.mk文件的 LOCAL_SRC_FILES后面加入包含该类或函数的文件,用\隔开,\后换行继续添加 例如 LOCAL_SRC_FILES := NDKTest.cpp\bncore. ...

  9. 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(老罗学习笔记2)

    在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序.在这个名为hello的Linux内核驱动程序中,创建三个不同的文件节点来供用户空间访问,分别是传统的设备文 ...

  10. jsp中四种传递参数的方法

    jsp中四种传递参数的方法如下: 1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="i ...