我正在尝试将一个大流(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();
}
}
答案 0 :(得分:3)
StringWriter
在内部写入StringBuffer
。 StringBuffer
基本上是char
数组的包装器。该阵列具有一定的容量。当容量不足时,StringBuffer
将分配一个新的较大char
数组并复制前一个数组的内容。最后,在StringWriter上调用toString()
,它将再次将char
数组的内容复制到生成的String的char
数组中。
如果您有任何预先知道所需容量的方法,则应使用StringWriter的构造函数来设置初始容量。这样可以避免不必要地复制数组以增加缓冲区。
然而,这并不能避免在toString()
中发生的最终副本。如果您正在处理可能很大的流,您可能需要重新考虑是否确实需要将该输入流作为String
。直接使用足够大的char
数组可以避免所有复制,并且会大大减少内存使用量。
最终解决方案是在输入所有输入之前对输入进行一些处理,以便可以丢弃已处理的字符。这样,您只需要在内存中保存与处理步骤所需的内容一样多。