遇到问题---java获取网络文件大小失败getContentLength()为-1 完整解决方法

时间:2022-10-08 03:33:38


下载的方式详见链接

java下载网络文件


获取网络大小使用的代码如下:

URL url=new   URL("http://yinyueshiting.baidu.com/data2/music/123296359/13132725248400128.mp3?xcode=bce09e68531be7afafd0ef4fac9a741419c56da7f7cc7a9f");   
HttpURLConnection urlcon=(HttpURLConnection)url.openConnection();
//根据响应获取文件大小
int fileLength=urlcon.getContentLength(); //这里获取的是字节
double fileLenM=Double.parseDouble(df.format((fileLength/1024.00)/1024.00)); //转为M


正常情况下能获取到 文件的大小

如果返回 -1,原因可能有很多种


首先排除 链接不正确或者服务器响应的问题 或者ip被屏蔽

假设我现在要获取 

http://yinyueshiting.baidu.com/data2/music/123296359/13132725248400128.mp3?xcode=bce09e68531be7afafd0ef4fac9a741419c56da7f7cc7a9f

链接的mp3的大小


则把该链接在浏览器的下载任务中新建 尝试下载

遇到问题---java获取网络文件大小失败getContentLength()为-1 完整解决方法

遇到问题---java获取网络文件大小失败getContentLength()为-1 完整解决方法




如果能下载,则说明链接正确,服务器也没问题,ip也没被屏蔽也就是我们的代码有问题。


网上一些解决方案说是HttpURLConnection 使用 gzip方式获取 的原因。

加上代码

urlcon.setRequestProperty("Accept-Encoding", "identity"); 
可以解决

详见

Android getContentLength()为-1 解决方法



如果上述方法仍然不行


那继续往下分析

我们在谷歌浏览器中访问这个链接

查看它的请求头以及response 发现response中是有content-length的 一般都会有

遇到问题---java获取网络文件大小失败getContentLength()为-1 完整解决方法


那我们的代码问题到底出在哪呢


一般可能是请求头的问题  导致被服务器拒绝访问了


我的就是这个原因


加上User-agent 伪装一下 伪装成浏览器 后就可以了

URL url;
url = new URL();
HttpURLConnection urlcon=(HttpURLConnection)url.openConnection();
urlcon.setRequestProperty("User-Agent", " Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36");
urlcon.setConnectTimeout(15000);
urlcon.setReadTimeout(15000);
//根据响应获取文件大小
fileLength=urlcon.getContentLength();
System.out.println("get fileLen "+fileLength);


如果还不能解决 那就得用fidder工具好好分析一下了

通过fidder分析 我们发出的请求头 request跟浏览器发出的 request 有哪些区别


浏览器的request很容易获取 


打开 fidder,fidder会自动获取到浏览器中输入的链接的 相关信息。

遇到问题---java获取网络文件大小失败getContentLength()为-1 完整解决方法



而我们代码 运行的request则需要在代码中 加 代理

指向本机的 fidder监听端口

工具----> fidder选项--->监听端口 可以查看端口

遇到问题---java获取网络文件大小失败getContentLength()为-1 完整解决方法



代码中加代理 

String host = "127.0.0.1";  
String port = "8888";
setProxy(host, port);
public static void setProxy(String host, String port) {
System.setProperty("proxySet", "true");
System.setProperty("proxyHost", host);
System.setProperty("proxyPort", port);
}

然后运行代码

fidder就能监听到 请求了 


对比一下 或者构造成跟 浏览器访问的一模一样 就绝对ok了


其实只要找到其中几个关键的 参数设置成一样的也是可以的