使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法
使用HttpURLConnection下载文件时经常会出现 java.io.FileNotFoundException文件找不到异常,下面介绍下解决办法
首先设置tomcat对get数据的编码:conf/server.xml
- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443"
- <span style="color:#ff0000;"> URIEncoding="UTF-8"</span> />
其次对请求的文件名进行编码:
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLEncoder;
- /**
- * 多线程下载
- * @author bing
- *
- */
- public class OmbDownloadOfThreadsUtil {
- private String urlPath ; // 资源网络路径
- private String targetFilePath ; // 所下载文件的保存路径
- private int threadNum ; // 启用多少条线程进行下载
- // 用于下载线程对象集合
- private DownloadThread[] downloadThreads ;
- // 要下载文件的大小
- private int fileSize ;
- public OmbDownloadOfThreadsUtil(String urlPath, String targetFilePath,
- int threadNum) {
- this.urlPath = urlPath;
- this.targetFilePath = targetFilePath;
- this.threadNum = threadNum;
- downloadThreads = new DownloadThread[threadNum] ;
- }
- public void downloadFile() throws Exception{
- URL url = new URL(urlPath) ;
- HttpURLConnection conn = (HttpURLConnection) url.openConnection() ;
- conn.setConnectTimeout(4*1000) ;
- conn.setRequestMethod("GET") ;
- conn.setRequestProperty(
- "Accept",
- "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
- "application/x-shockwave-flash, application/xaml+xml, " +
- "application/vnd.ms-xpsdocument, application/x-ms-xbap, " +
- "application/x-ms-application, application/vnd.ms-excel, " +
- "application/vnd.ms-powerpoint, application/msword, */*");
- conn.setRequestProperty("Accept-Language", "zh-CN");
- conn.setRequestProperty("Charset", "UTF-8");
- //设置浏览器类型和版本、操作系统,使用语言等信息
- conn.setRequestProperty(
- "User-Agent",
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/4.0; " +
- ".NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; " +
- ".NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
- //设置为长连接
- conn.setRequestProperty("Connection", "Keep-Alive");
- //得到要下载文件的大小
- fileSize = conn.getContentLength() ;
- System.out.println("fileSize:"+fileSize);
- //断开连接
- conn.disconnect() ;
- //计算每条线程需要下载的大小
- int preThreadDownloadSize = fileSize/threadNum+1 ;
- System.out.println("preThreadDownloadSize:"+preThreadDownloadSize);
- RandomAccessFile file = new RandomAccessFile(targetFilePath, "rw") ;
- file.setLength(fileSize) ;
- file.close() ;
- for (int i = 0; i < threadNum; i++) {
- // 计算每条线程下载的起始位置
- int startPos = i*preThreadDownloadSize+1 ;
- RandomAccessFile currentPart = new RandomAccessFile(targetFilePath, "rw") ;
- currentPart.seek(startPos) ;
- downloadThreads[i] = new DownloadThread(startPos,preThreadDownloadSize,currentPart) ;
- new Thread(downloadThreads[i]).start() ;
- }
- }
- /**
- * 获取下载的完成百分比
- * @return 完成的百分比
- */
- public double getCompleteRate() {
- // 统计多条线程已经下载的总大小
- int sumSize = 0;
- for (int i = 0; i < threadNum; i++) {
- sumSize += downloadThreads[i].hasReadLength;
- }
- // 返回已经完成的百分比
- return sumSize * 1.0 / fileSize;
- }
- /**
- * 用于下载的线程
- * @author bing
- *
- */
- private final class DownloadThread implements Runnable{
- private int startPos ;
- private int preThreadDownloadSize ;
- private RandomAccessFile currentPart ;
- //已下载长度
- private int hasReadLength ;
- public DownloadThread(int startPos, int preThreadDownloadSize,
- RandomAccessFile currentPart) {
- this.startPos = startPos;
- this.preThreadDownloadSize = preThreadDownloadSize;
- this.currentPart = currentPart;
- }
- @Override
- public void run() {
- InputStream inputStream = null ;
- try{
- URL url = new URL(urlPath) ;
- HttpURLConnection conn = (HttpURLConnection) url.openConnection() ;
- conn.setConnectTimeout(4*1000) ;
- conn.setRequestMethod("GET") ;
- conn.setRequestProperty(
- "Accept",
- "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
- "application/x-shockwave-flash, application/xaml+xml, " +
- "application/vnd.ms-xpsdocument, application/x-ms-xbap, " +
- "application/x-ms-application, application/vnd.ms-excel, " +
- "application/vnd.ms-powerpoint, application/msword, */*");
- conn.setRequestProperty("Accept-Language", "zh-CN");
- conn.setRequestProperty("Charset", "UTF-8");
- inputStream = conn.getInputStream() ;
- inputStream.skip(startPos) ;//定位到开始位置
- byte[] buffer = new byte[1024] ;
- int temp = 0 ;
- while(hasReadLength<preThreadDownloadSize
- &&(temp=inputStream.read(buffer))!=-1){
- currentPart.write(buffer,0,temp) ;
- hasReadLength += temp ;
- }
- }catch(Exception e){
- e.printStackTrace() ;
- }finally{
- try {
- currentPart.close() ;
- } catch (Exception e) {
- e.printStackTrace();
- }
- try {
- inputStream.close() ;
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- public static void main(String[] args) throws Exception {
- String songName = "许嵩 - 半城烟沙.mp3" ;
- songName = URLEncoder.encode(songName,"UTF-8") ;
- String urlPath = "http://172.16.2.50:8080/mp3/"+songName ;
- String targetDir = "E:"+File.separator+songName ;
- OmbDownloadOfThreadsUtil odtu = new OmbDownloadOfThreadsUtil(urlPath,targetDir, 6) ;
- odtu.downloadFile() ;
- }
- }
经过以上三步基本上问题已经解决,但如果的文件名含有空格的话还需一步:
URLs是不能包含空格的。URL encoding一般会使用“+”号去替换空格,但后台服务器(我的是Tomcat6.0)又不能把“+”还原为空格,所以导致文件找不到,解决办法:只需把“+”替换为“%20”
- public static void main(String[] args) throws Exception {
- String songName = "许嵩 - 半城烟沙.mp3" ;
- songName = URLEncoder.encode(songName,"UTF-8").replace("+", "%20") ;
- String urlPath = "http://172.16.2.50:8080/mp3/"+songName ;
- String targetDir = "E:"+File.separator+songName ;
- OmbDownloadOfThreadsUtil odtu = new OmbDownloadOfThreadsUtil(urlPath,targetDir, 6) ;
- odtu.downloadFile() ;
- }
使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法的更多相关文章
- MS SQL执行大脚本文件时,提示“内存不足”的解决办法()
问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当数据库导出脚本很大,用Microsoft SQL Server Management Studio执行 ...
- MS SQL2008执行大脚本文件时,提示“内存不足”的解决办法
问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当数据库导出脚本很大,用Microsoft SQL Server Management Studio执行 ...
- MSSQL执行大脚本文件时,提示“内存不足”的解决办法
导出了一个脚本文件,将近900M,回来往sql studio一丢,报了个内存不足,然后就有了此文.. 问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当 ...
- SQL SERVER 2008R2 执行大脚本文件时,提示“内存不足”的解决办法
我把一个数据库的架构及数据都已脚本的方式拷贝下来,再去新建一个数据库想把脚本执行一下,但提示如下错误: 问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是 ...
- 使用Android SDK Manager下载sdk时总是出现中断异常的解决办法。
1.搜到到你本机的hosts文件. 2.打开该文件. 3.在该文件最后一行添加:74.125.31.136 dl-ssl.google.com 4.重新下载问题解决. 参考链接:http://bbs. ...
- 关于在工程中添加新文件时的LNK2019错误的一个解决办法
我这几天一直在研究Qt的串口程序,在读懂了官方给出的实例程序后我决定把其多线程的串口监视程序加入到我自己的工程中,便直接把问价复制到自己的工程下面,在Qt中加入到自己的工程中,但是总是出现LNK201 ...
- flask上传文件时request.files为空的解决办法
在做上传文件的时候遇到request.files是空 原因在于html中的表单form没有指明 enctype="multipart/form-data" <form met ...
- GraphicsMagick java.io.FileNotFoundException: gm 错误解决办法
GraphicsMagick java.io.FileNotFoundException: gm 解决办法, 方法一: ProcessStarter.setGlobalSearchPath(" ...
- Android下载文件提示文件不存在。。。 java.io.FileNotFoundException
遇到这个错误java.io.FileNotFoundException,事实上文件是存在的,把地址复制到手机浏览器都能够直接下载的,但为嘛不能下载呢. Error in downloadBitmap ...
随机推荐
- POJ 1674
#include<iostream>//cheng da cai zi 08 .11 .13 using namespace std; int main() { int digit_num ...
- 深入理解JVM--类的执行机制
在完成将class文件信息加载到JVM并产生class对象之后,就可以执行Class对象的静态方法或者实例方法对对象进行调用了.JVM在源代码编译阶段将源代码编译为字节码文件,字节码是一种中间代码的方 ...
- jsp片段
转载自:http://blog.csdn.net/lovejavaydj/article/details/7293145 使用jspf 在开发中写jsp页面时,通常都要通过如下方式在jsp文件头部引入 ...
- Mysql 分页语句Limit用法
转载自:http://qimo601.iteye.com/blog/1634748 1.Mysql的limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用 ...
- HDU5087——Revenge of LIS II(BestCoder Round #16)
Revenge of LIS II Problem DescriptionIn computer science, the longest increasing subsequence problem ...
- 基于nginx的tomcat负载均衡和集群
要集群tomcat主要是解决SESSION共享的问题,因此我利用memcached来保存session,多台TOMCAT服务器即可共享SESSION了. 你可以自己写tomcat的扩展来保存SESSI ...
- Linux Shell脚本读写XML文件
在Linux下如何用Shell脚本读写XML?现有一个config.xml <?xml version="1.0" encoding="UTF-8"?&g ...
- hadoop拾遗(一)---- 避免切分map文件
有些程序可能不希望文件被切分,而是用一个mapper完整处理每一个输入文件.例如,检查一个文件中所有记录是否有序,一个简单的方法是顺序扫描第一条记录并并比较后一条记录是否比前一条要小.如果将它实现为一 ...
- maven小试牛刀
Maven是一个采用纯Java编写的开源项目管理工具.Maven采用了一种被称之为project object model (POM)概念来管理项目,所有的项目配置信息都被定义在一个叫做POM.xml ...
- ios中addtarget
Target-action:目标-动作模式,它贯穿于iOS开发始终.但是对于初学者来说,还是被这种模式搞得一头雾水. 其实Target-action模式很简单,就是当某个事件发生时,调用那个对象中的那 ...