首页 > 其他 > 详细

使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法

时间:2014-02-17 19:45:45      阅读:692      评论:0      收藏:0      [点我收藏+]

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

 

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

 

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

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

 

 

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


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

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

 

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

使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法

原文:http://www.cnblogs.com/duanxz/p/3552590.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!