StringBuilder追加导致内存不足

时间:2013-10-01 05:22:55

标签: java android

我在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();

我的内存分配错误。请帮忙。我尝试了许多方法,但也没有做到正确。

3 个答案:

答案 0 :(得分:0)

可能有两个问题。 第一个 - 周期for (String line = null; (line = br.readLine()) != null ; )未正确终止。尝试通过打开一个小文件来找到它(例如总共10行)。

第二个 - 它实际上是一个记忆不足的情况。可能通过字符串获取图像并不是最好的想法,因为图像可能非常沉重并且创建大量字符串会导致自然内存错误。尝试寻找另一种方法。

答案 1 :(得分:0)

如果您要下载图片,则不应使用Reader/Writer/StringBuilder来存储图片内容。由于character encoding类使用Reader/Writer,因此文件是二进制内容将被加扰。

尝试使用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);
}

答案 2 :(得分:0)

我没有看到实际写入输出流的代码。收盘前不应该有一条线,就像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(这肯定是有帮助的),但然后会继续,这将没有那么有用。只需在每个return之后添加printstackTrace
  • 一条线路的存储空间可能太长,但风险最小化。
  • 您下载的数据是二进制图像还是文本?您将其命名为图像但下载文本。请注意,字节和字符之间存在差异(使用字符集编码)并保持在实际接收的范围内。