簡體   English   中英

StringBuilder追加導致內存不足

[英]StringBuilder append cause out of memory

我在asynctask中失去內存錯誤,循環到stringbuilder。 我的目標是使用它從服務器下載圖像並存儲在我的SD卡內。我的代碼如下:

HttpClient httpclient = new DefaultHttpClient();
        httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);   
        HttpPost httppost = new HttpPost(severPath);        

        httppost.setEntity(params[0]);
        System.out.println("executing request " + httppost.getRequestLine());



            HttpResponse response = null;
            try {
                response = httpclient.execute(httppost);
            } catch (ClientProtocolException e6) {
                // TODO Auto-generated catch block
                e6.printStackTrace();
            } catch (IOException e6) {
                // TODO Auto-generated catch block
                e6.printStackTrace();
            }
            String output;
            System.out.println("Output from Server .... \n");

            BufferedReader br = null;
            try {
                br = new BufferedReader(
                        new InputStreamReader((response.getEntity().getContent())));
            } catch (IllegalStateException e5) {
                // TODO Auto-generated catch block
                e5.printStackTrace();
            } catch (IOException e5) {
                // TODO Auto-generated catch block
                e5.printStackTrace();
            }

             OutputStreamWriter outputStreamWriter = null;
            try {
                outputStreamWriter = new OutputStreamWriter(context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE));
            } catch (FileNotFoundException e6) {
                // TODO Auto-generated catch block
                e6.printStackTrace();
            }
            int i = 0;


            StringBuilder builder = new StringBuilder();


            String Result = "";
                try {
                    for (String line = null; (line = br.readLine()) != null ; ) {
                                        builder.append(line.toString());

                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }




                    outputStreamWriter.close();

我沒有內存分配錯誤。 請幫忙。 我嘗試了很多方法,但也沒有做到正確。

可能有兩個問題。 第一個 - for (String line = null; (line = br.readLine()) != null ; )的循環未正確終止。 嘗試通過打開一個小文件找到它(例如總共10行)。

第二個 - 它實際上是一個記憶不足的情況。 可能通過字符串獲取圖像並不是最好的想法,因為圖像可能非常沉重並且創建大量字符串會導致自然內存錯誤。 嘗試尋找另一種方法。

如果您正在下載圖像,則不應使用Reader/Writer/StringBuilder來存儲它的內容。 因為文件是二進制內容,所以會因為Reader/Writer類使用的character encoding而被加擾。

嘗試使用InputStream/OutputStream並將內容直接存儲到SD卡而不將其存儲在內存中。

試試下面的代碼:

InputStream in = response.getEntity().getContent();
OutputStream out = context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE);
byte b[] = new byte[4096];
int i;
while ((i = in.read(b)) >= 0) {
    out.write(b, 0, i);
}

我沒有看到實際寫入輸出流的代碼。 關閉前不應該有一行,就像outputStreamWriter.print(builder)

關於你的問題。 您應該直接在for-loop中直接寫入每一行,而不是在StringBuilder中將整個數據收集到內存中,而不是一次寫入。 您根本不需要StringBuilder。 這是一段代碼片段:

            try {
                for (String line = br.readLine(); line != null; line = br.readLine()) {
                    outputStreamWriter.append(line);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return;
            }

還有三點評論:

  • 當你得到一個異常時,你也應該停止動作,例如從你的方法返回。 您上面的代碼將打印Stacktrace(這肯定是有幫助的),但然后會繼續,這將沒有那么有用。 只需在每個printstackTrace之后添加return
  • 一條線路的存儲空間可能太長,但風險最小化。
  • 您下載的數據是二進制圖像還是文本? 您將其命名為圖像但下載文本。 請注意,字節和字符(用字符集編碼)之間存在差異,並保持在實際接收的范圍內。

暫無
暫無

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

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