6

我有一个 URL,当我在浏览器中输入时,它会完美地打开图像。但是当我尝试以下代码时,我得到 getContentLength() 为 -1:

URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

// determine the image size and allocate a buffer
int fileSize = connection.getContentLength();

请指导我这背后的原因是什么?

4

2 回答 2

8

如果服务器使用分块传输编码发送响应,您将无法预先计算大小。响应是流式传输的,您只需分配一个缓冲区来存储图像,直到流完成。请注意,仅当您可以保证图像足够小以适合内存时才应该这样做。如果图像可能很大,将响应流式传输到闪存存储是一个非常合理的选择。

内存解决方案:

private static final int READ_SIZE = 16384;

byte[] imageBuf;
if (-1 == contentLength) {
    byte[] buf = new byte[READ_SIZE];
    int bufferLeft = buf.length;
    int offset = 0;
    int result = 0;
    outer: do {
        while (bufferLeft > 0) {
            result = is.read(buf, offset, bufferLeft);
            if (result < 0) {
                // we're done
                break outer;
            }
            offset += result;
            bufferLeft -= result;
         }
         // resize
         bufferLeft = READ_SIZE;
         int newSize = buf.length + READ_SIZE;
         byte[] newBuf = new byte[newSize];
         System.arraycopy(buf, 0, newBuf, 0, buf.length);
         buf = newBuf;
     } while (true);
     imageBuf = new byte[offset];
     System.arraycopy(buf, 0, imageBuf, 0, offset);
 } else { // download using the simple method

理论上,如果 Http 客户端将自己呈现为 HTTP 1.0,大多数服务器将切换回非流模式,但我不认为 URLConnection 有这种可能性。

于 2012-05-03T22:24:30.100 回答
0

我在这里迟到了,但这可能会对某人有所帮助。我遇到了同样的问题,当我尝试获取内容长度时,我总是得到 -1 值。

以前我使用下面的方法来获取内容长度。

long totalByte=connection.getContentLength();

下面解决了我的问题:-

long totalByte=Long.parseLong(connection.getHeaderField("Content-Length"));
于 2021-10-12T10:25:41.313 回答