簡體   English   中英

(java)HttpEntity.getContent()輸出受限的InputStream(8192b / 7748b)…我正在嘗試下載2.4MB文件

[英](java) HttpEntity.getContent() outputs limited InputStream (8192b / 7748b) … I'm trying to download a 2.4MB file

我正在使用Apache HttpClient 4.5 ,試圖下載2.4 MB的文件 文件在Chrome中可用並且可以完全下載。

問題是, InputStream is由歸國entity.getContent()只包含8192字節的緩沖區,並is.available()返回7748.私人提起contentLengthis為2488649,這應該是所需的文件大小,所以我不明白問題是什么。 我在“調試”的“變量”模塊中找到的所有緩沖區大小均為8192。

試圖取代 is在現場用FileInputStream瞄准我的電腦上相同的文件。 傳輸完美,全部2.4 MB。 所以我想我在http utils配置上做錯了什么。

請幫我解決這個問題。 該代碼似乎有點長,但是應該很容易理解。

CommRunnable。 下面的類的基類:

public abstract class CommRunnable implements Runnable {
    protected HttpPostAgent agent;
    protected boolean success;

    //...additional methods...//
}

GetFileRunnable。 在單獨的線程中運行。 啟動連接和文件傳輸:

public class GetFileRunnable extends CommRunnable implements Runnable {
    private String url;
    private String fileDestination;
    private NameValuePair[] postPairs;

    //...constructor...//

    public void run() 
    {
        synchronized (agent) {
            try {
                HttpClient client = HttpClients.createDefault();

                HttpResponse response = agent.getHttpResponse(client, url, postPairs);

                InputStream is = response.getEntity().getContent();
                FileOutputStream fos = new FileOutputStream(fileDestination);

                success = agent.transfer(is, fos);

                client.getConnectionManager().shutdown();

            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("IOException in HttpPostAgent.getFile");
            } finally {
                agent.setFree(true);
            }
        }
    }
}

HttpPostAgent。 基本上是Apache http實用程序的控制器。 方法在其上方的注釋中進行了描述。

public class HttpPostAgent {
    private int statusPerc;
    private boolean free;

    private Thread thread;
    private CommRunnable currentAction;

    //...constructor...//

    //executes POST request and returns resulting HttpResponse
    HttpResponse getHttpResponse(HttpClient client, String url, NameValuePair... postPairs)
    {
        try {
            List <NameValuePair> nvps = new ArrayList <NameValuePair>();

            for (NameValuePair pair : postPairs)
                nvps.add(pair);

            HttpPost post = new HttpPost(url);
            post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

            return client.execute(post);

        } catch (IOException e) {
            throw new RuntimeException("IOException in getHttpResponse(HttpClient client, String url, NameValuePair... postPairs)");
        }
    }

    //...methods...//

    //Starts thread with GetFileRunnable. Included here for Your understanding of my context.
    public void getFileInit(String url, String destinationPath, NameValuePair... postPairs)
    {
        free = false;
        statusPerc = 0;
        currentAction = new GetFileRunnable(this, url, destinationPath, postPairs);
        thread = new Thread(currentAction);
        thread.setPriority(Thread.MIN_PRIORITY);
        thread.setDaemon(true);
        thread.start();
    }

    //...methods...//

    //Transfers a file from one input stream to the other. For downloading from response/entity/content.
    boolean transfer(InputStream is, OutputStream os)
    {
        boolean success = false;

        try {
            int remain = is.available();
            int total = remain;
            int read = 0;
            int chunk = 1024;
            byte[] buffer = new byte[chunk];

            while(remain > 0)
            {
                if(chunk > remain) chunk = remain;

                os.flush();
                is.read(buffer, 0, chunk);
                os.write(buffer, 0, chunk);

                remain -= chunk;
                read += chunk;

                synchronized (this) {
                    statusPerc = (read * 100) / total;
                }
            }
            remain = is.available();

            success = true;

        } catch (IOException e) {
            throw new RuntimeException("IOException in HttpPostAgent.transfer");
        } 

        return success;
    }

    //...methods...//
}

請告訴我是否應該添加更多信息。

InputStream.available()的Javadoc中:

返回可以從此輸入流讀取(或跳過)而不會被該輸入流的方法的下一次調用阻塞的字節數的估計值。

因此,可用字節不是總輸入字節,而是開始讀取輸入時已緩沖的第一個字節塊。 8192似乎是您的示例中的緩沖區大小。

因此,您的HttpPostAgent.transfer方法僅有效處理前8192個字節,然后停止。

您可以嘗試使用以下替代HttpPostAgent.transfer方法嗎?

boolean transfer(InputStream is, OutputStream os) throws IOException
{
    byte buffer[] = new byte[2048];
    int count;
    while ((count = is.read(buffer)) != -1)
        os.write(buffer, 0, count);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM