簡體   English   中英

將大流轉換為字符串時內存不足

[英]out of memory when converting a large stream to string

我正在嘗試將大流(4mb)轉換為字符串,最終將其轉換為 JSON 數組。

當流大小很小(以 KB 為單位)時,一切正常,當它開始處理 4mb 流時,它就會耗盡內存

下面是我用來將流轉換為字符串的方法,我幾乎嘗試了所有方法,但我懷疑問題出在 while 循環上。 有人可以幫忙嗎?

  public String convertStreamToString(InputStream is)
            throws IOException {

        if (is != null) {
            Writer writer = new StringWriter();

            char[] buffer = new char[1024];
            try
            {
                Reader reader = new BufferedReader(
                        new InputStreamReader(is, "UTF-8"));
                int n;
                while ((n = reader.read(buffer)) != -1) 
                {
                    writer.write(buffer, 0, n);
                }
            }
            finally 
            {
                is.close();
            }
            return writer.toString();
        } else {       
            return "";
        }
    }

更新:好的,這是我目前到達的地方,我在正確的軌道上嗎? 我想我已經接近了.. 不知道我還能關閉或刷新什么來恢復記憶..

public String convertStreamToString(InputStream is)
        throws IOException {

    String encoding = "UTF-8";
    int maxlines = 2000;
    StringWriter sWriter = new StringWriter(7168);
    BufferedWriter writer = new BufferedWriter(sWriter);
    BufferedReader reader = null;
    if (is == null) {
        return "";
    } else {     


        try {
            int count = 0;
            reader = new BufferedReader(new InputStreamReader(is, encoding));
            for (String line; (line = reader.readLine()) != null;) {
                if (count++ % maxlines == 0) {
                    sWriter.close();
                    // not sure what else to close or flush here to regain memory
                    //Log.v("Max Lines Reached", "Max Lines Reached");;
                }

                writer.write(line);


            }
            Log.v("Finished Loop", "Looping over");


    } finally {
        is.close();
        writer.close();

    }
        return writer.toString();
    }
}

StringWriter在內部寫入StringBuffer StringBuffer基本上是一個圍繞char數組的包裝器。 該陣列具有一定的容量。 當該容量不足時, StringBuffer將分配一個新的更大的char數組並復制前一個的內容。 最后,您在 StringWriter 上調用toString() ,它將再次將char數組的內容復制到結果字符串的char數組中。

如果您有任何事先知道所需容量的方法,您應該使用 StringWriter 的構造函數來設置初始容量。 這將避免不必要地復制數組以增加緩沖區。

但這並不能避免發生在toString()的最終副本。 如果您正在處理可能很大的流,您可能需要重新考慮是否真的需要將該 inputstream 作為String 直接使用足夠大的char數組可以避免所有的復制,並且會大大減少內存使用。

最終的解決方案是在所有輸入進入之前對輸入進行一些處理,這樣可以丟棄已處理的字符。 這樣,您只需要在內存中保存處理步驟所需的內容。

暫無
暫無

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

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