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

サーバーがChunked Transfer Encodingを使用して応答を送信している場合、サイズを事前に計算することはできません。応答はストリーミングされます。ストリームが完了するまで、画像を格納するためのバッファーを割り当てる必要があります。イメージがメモリに収まるほど小さいことが保証できる場合にのみ、これを行う必要があることに注意してください。イメージが大きい可能性がある場合、フラッシュ ストレージへの応答をストリーミングすることは非常に妥当なオプションです。

インメモリ ソリューション:

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 に答える