繁体   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