我正在开发一个应用程序,在第一次启动时,我预计会以JSON格式下载大量数据(例如10-20 MB)。所有这些数据都在一个网络请求中传输(原因是数据是按请求动态生成的)。 fllowing代码在接收数据(in builder.append()
)时抛出OOM异常:
public static String readToString(InputStream stream) throws IOException {
BufferedReader in = null;
StringBuilder builder = new StringBuilder();
in = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
char[] buffer = new char[1024];
int read = 0;
while ((read = in.read(buffer, 0, 1024)) > 0) {
builder.append(buffer, 0, read);
}
in.close();
return builder.toString();
}
我该怎么做才能避免此错误?我正在考虑尝试将数据保存到临时文件然后处理它。但我不确定它是否会起作用。 另一种可能性似乎是将网络IO分为两部分:第一部分,应用程序接收有关应下载内容的数据,第二部分实际下载数据。
有什么建议吗?
答案 0 :(得分:3)
按照您的第一个想法 - 将数据保存到临时文件(请使用SD卡。内部存储空间中的20mb太大)。您首先需要打开下载连接。
InputStream is = URL("your_request_string").openStream();
然后在sdcard中创建一个新文件
File f = new File(Environment.getExternalStorageDirectory(), "temp.dat");
使用新创建的文件,打开OutputStream。
FileOutputStream = new FileOutputStream(f);
您现在可以使用这段代码进行转移:
public static void CopyStream(InputStream is, OutputStream os) {
final int buffer_size=8192;
try
{
byte[] bytes=new byte[buffer_size];
for(;;)
{
int count=is.read(bytes, 0, buffer_size);
if(count==-1)
break;
os.write(bytes, 0, count);
}
}
catch(Exception ex){}
}
答案 1 :(得分:1)
从API 11开始,有http://developer.android.com/reference/android/util/JsonReader.html用于读取Json数据流而不分配整个大字符串。
对于以前的版本,有大量第三方JSON库提供基于事件的流读取功能。