簡體   English   中英

使用 InputStream 下載大文件

[英]Download large files using InputStream

我們有一個在 Linux 上運行的 Weblogic 服務器,它有多個托管服務器。 我關心的托管服務器的最大堆大小為 1024MB。 該服務器上部署了多個應用程序。 其中一個應用程序處理來自 REST api 的響應以下載 250MB 大的文件。 對於大於 50 MB 的文件,有時沒有問題,但有時服務器會因 OOM 錯誤而崩潰。 以下是我的代碼:

Client client = Client.create();          
WebResource webResource = client.resource(url.toString());
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
            throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());
        }
String output = response.getEntity(String.class);
byte[] fileContent = Base64.decodeBase64(output.getBytes());
if (fileContent != null) {
        OutputStream out = null;
        try {
            res.reset();
            out = res.getOutputStream();
            res.setContentType(contentType);
            res.setHeader("Content-Disposition", "inline; filename=" + fileName + "; size=" + String.valueOf(fileContent.length));
            res.setContentLength(fileContent.length);
            out.write(fileContent);
        } catch (Exception ex) {
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
        }
    } 

由於存在 memory 問題,我嘗試采用 InputStream 方法。 以下是更改后的代碼:

Client client = Client.create();          
WebResource webResource = client.resource(url.toString());
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
        throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());
    }
InputStream source = response.getEntityInputStream(); // IS THIS OKAY?

if (source!= null) {
        OutputStream out = null;
        int count = 0;
        try {
            byte[] buffer = new byte[1024];
            int read = 0;
            res.reset();
            res.setContentType(contentType);
            res.setHeader("Content-Disposition", "inline; filename=" + fileName);
            out = res.getOutputStream();
            while ((read = source.read(buffer)) != -1) {
                out.write(buffer, 0, read);
                count++;
            }                
            System.out.println("COUNT: " + count);// For a 60MB file, this prints 86000. why?
        } catch (Exception ex) {
            e.printStackTrace();
        }finally{
            out.flush();
            out.close();
            source.close();
        }

此代碼不會遇到 OOM,但文件無法加載/已損壞。 問題是否與它是 Base64 編碼響應而我處理不當有關? 如果是,我該怎么辦? 該應用程序在 Java 上運行 7. 我使用 InputStream 解決 OOM 的方法好嗎? 該服務沒有以塊的形式發送響應。 我還有什么其他方法可以 go 領先? 我擔心我會在 50MB 的文件中遇到錯誤(並非總是如此)。 服務器是遠程服務器,由另一組處理。 如何檢查是否有其他原因導致服務器崩潰?

嗨試試這個指南。 https://www.baeldung.com/java-download-file

這是一個很棒的網站,它提供了幾乎所有可以想象的場景的許多 Java 指南。

祝你好運: :-)

我使用 Base64InputStream 來解碼 InputStream 響應,它工作正常。

InputStream stream = response.getEntityInputStream();
Base64InputStream bis = new Base64InputStream(stream);

然后,使用 bis 寫入文件。 這種方法現在打印 65000 左右的計數變量。

暫無
暫無

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

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