Java StringBuilder追加导致内存不足
循环到stringbuilder的asynctask中出现内存不足错误。我的目标是使用它从服务器下载图像并存储在我的sd卡中。我的代码如下:Java StringBuilder追加导致内存不足,java,android,Java,Android,循环到stringbuilder的asynctask中出现内存不足错误。我的目标是使用它从服务器下载图像并存储在我的sd卡中。我的代码如下: HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppo
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();
我的内存分配出错。请帮忙。我尝试了很多方法,但也没有找到正确的方法。可能有两个问题。
第一个-未正确终止(String line=null;(line=br.readLine())!=null;)的循环。试着打开一个小文件(例如总共10行)来找出答案
第二,这实际上是一个内存不足的情况。通过字符串获取图像可能不是最好的方法,因为图像可能非常沉重,创建大量字符串会导致自然内存错误。尝试另一种方法。如果您正在下载图像,则不应使用Reader/Writer/StringBuilder
存储图像内容。由于文件是二进制文件,因此由于读写器
类使用的字符编码
,内容将被置乱
尝试使用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)
关于你的问题。与在StringBuilder中收集内存中的全部数据并立即写入不同,您应该直接写入for循环中的每一行。您根本不需要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
- 仍然有可能一行对于内存来说太长,但是风险最小化了
- 您下载的数据是二进制图像还是文本?你把它命名为图像,但你下载文本。请注意,字节和字符(用字符集编码)之间存在差异,请保持在实际接收的范围内
循环迭代了多少次?For循环在没有更多行可用后是否正确终止?能否稍微扩展代码?@GurminderSingh相当多,直到导致内存分配不足error@user2310289仍然有台词,但是没有了memory@nick,我刚加了。