pra*_*eep 9 java android httpurlconnection
这是我的代码:
url = paths[0];
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int length = connection.getContentLength(); // i get negetive length
InputStream is = (InputStream) url.getContent();
byte[] imageData = new byte[length];
int buffersize = (int) Math.ceil(length / (double) 100);
int downloaded = 0;
int read;
while (downloaded < length) {
if (length < buffersize) {
read = is.read(imageData, downloaded, length);
} else if ((length - downloaded) <= buffersize) {
read = is.read(imageData, downloaded, length - downloaded);
} else {
read = is.read(imageData, downloaded, buffersize);
}
downloaded += read;
publishProgress((downloaded * 100) / length);
}
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0,
length);
if (bitmap != null) {
Log.i(TAG, "Bitmap created");
} else {
Log.i(TAG, "Bitmap not created");
}
is.close();
return bitmap;
Run Code Online (Sandbox Code Playgroud)
我在Java文档中查看了这个,由于以下原因,长度为负:
"内容的字节数,如果未知则为负数.如果内容>长度已知但超过Long.MAX_VALUE,则返回负数."
可能是什么原因?我正在尝试下载图像.我想指出这是我尝试下载图像的第四种方法.其他三个在这里提到.
编辑:
根据要求,这是我正在使用的完整方法.
protected Bitmap getImage(String imgurl) {
try {
URL url = new URL(imgurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int length = connection.getContentLength();
InputStream is = (InputStream) url.getContent();
byte[] imageData = new byte[length];
int buffersize = (int) Math.ceil(length / (double) 100);
int downloaded = 0;
int read;
while (downloaded < length) {
if (length < buffersize) {
read = is.read(imageData, downloaded, length);
} else if ((length - downloaded) <= buffersize) {
read = is.read(imageData, downloaded, length
- downloaded);
} else {
read = is.read(imageData, downloaded, buffersize);
}
downloaded += read;
// publishProgress((downloaded * 100) / length);
}
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0,length);
if (bitmap != null) {
System.out.println("Bitmap created");
} else {
System.out.println("Bitmap not created");
}
is.close();
return bitmap;
} catch (MalformedURLException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
} catch (Exception e) {
System.out.println(e);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
Jér*_*ire 29
默认情况下,HttpURLConnection的此实现请求服务器使用gzip压缩.
由于getContentLength()返回传输的字节数,因此无法使用该方法来预测可从getInputStream()读取的字节数.
相反,读取该流直到它耗尽:当read()返回-1时.
可以通过在请求标头中设置可接受的编码来禁用Gzip压缩:
urlConnection.setRequestProperty("Accept-Encoding", "identity");
Run Code Online (Sandbox Code Playgroud)
试试这个:
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Encoding", "identity"); // <--- Add this line
int length = connection.getContentLength(); // i get negetive length
Run Code Online (Sandbox Code Playgroud)
来源(绩效段落):http://developer.android.com/reference/java/net/HttpURLConnection.html
Ste*_*n C 12
简单的答案是内容长度未知.或者更具体地说,服务器没有在响应消息中设置"Content-Length"头.
您将不得不更改代码,以便它不预先分配固定大小的字节数组来保存图像.
另一种方法是创建ByteArrayOutputStream从套接字读取的本地和复制字节.然后调用toByteArray以获取完整的字节数组.
如果您可以更改服务器端,另一种方法是在响应中设置内容长度标头.必须在使OutputStream将图像字节写入响应之前完成此操作.
您现有的代码也在另一个方面被打破.如果您收到IOException或其他异常,代码块将"异常退出"而不关闭URLConnection.这将导致文件描述符的泄漏.执行此操作太多次,并且您的应用程序将因文件描述符...或本地端口号耗尽而失败.
最佳做法是使用try/finally确保始终关闭外部资源的URLConnections,Sockets,Streams等.