簡體   English   中英

從URL讀取InputStream並寫入HttpServletResponse而不創建臨時文件

[英]Read an InputStream from a URL and Write to HttpServletResponse without creating a temp file

我嘗試從URL讀取一個InputStream並直接寫入HttpServletResponse而不在HttpServlet中創建臨時文件,但未能獲得該文件的實際Content-Length。 我被告知,如果不讀取數據,我無法確定流中的數據量。 有人能幫我嗎? 我真的很感激。

由於您正在讀取URL,因此您應該從該URL的Content-length標頭中獲取Content-length

HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.connect();
if ( connection.getResponseCode() == 200 ) {
    int contentLength = connection.getContentLength();
    response.setContentLength( contentLength );

請注意,你應該使用inputStream.available() available()方法只是告訴你可以在不阻塞的情況下讀取多少字節(即等待下一個塊從網絡到達)。 它沒有告訴你流的大小! 但是在HttpURLConnection ,您可以使用getContentLength()方法獲取content-length頭的值。

一旦這樣做,您就可以啟動讀寫循環來復制所有數據,例如

InputStream source = connection.getInputStream();
OutputStream target = response.getOutputStream();

int FILE_CHUNK_SIZE = 1024 * 4;
byte[] chunk = new byte[FILE_CHUNK_SIZE]; 
int n =0;
while ( (n = source.read(chunk)) != -1 ) {
    target.write(chunk, 0, n);
}

請記住在所有這些中使用try-catch,因為在這樣的事務中可能會拋出多種異常。 當您發現異常時,請記住在響應中設置響應代碼,該代碼不是 200。

在數據耗盡之前,沒有理由無法從請求對象中讀取輸入流 - 將其緩沖到內存中。 事實上,根據我的經驗,這總是如何完成的; 我可以指望一只手的手指我看到輸入流寫入文件而不是緩沖到內存中的次數。 如果你得到一個內容長度標題,你可以用它作為起點,但我不會依賴它。 你需要防止太多的輸入,因為你不知道輸入流的遠端是什么,所以他們服務器你正在聯系你可能會發送很多材料,你用盡RAM來處理它。

只需繼續調用read()直到得到-1。 其他讀取方法也可用於此,但您將添加更多邏輯來檢測文件結束。

我使用這段代碼,沒有進行內容長度管理(IOUtils在commons-io中並且不創建臨時文件)但是適用於小文件和大文件:

public static void downloadFile(HttpServletResponse response, InputStream inputStream, String fileName,
        String contentType) throws IOException {

    response.reset();
    response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"",
            fileName));

    if (contentType != null) {
        response.setHeader("Content-Type", contentType);
    }

    OutputStream output = response.getOutputStream();

    IOUtils.copy(inputStream, output);

    output.flush();
    output.close();
}

暫無
暫無

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

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