Java 如何在android应用程序上读取大型Base64文件(150MB)?
我正在尝试在android应用程序上读取大小为Java 如何在android应用程序上读取大型Base64文件(150MB)?,java,android,Java,Android,我正在尝试在android应用程序上读取大小为(~150MB)的大型base64文本文件 该文件包含JSON字符串,我需要将其解码并转换为JSON对象,然后在应用程序中使用它。问题是,在尝试读取此数据时,内存中出现异常 该应用程序需要脱机工作,因此我需要下载完整数据 代码如下: String localPath = getApplicationContext().getFilesDir().getPath().toString() ; String key = "dataFile
(~150MB)
的大型base64
文本文件
该文件包含JSON字符串,我需要将其解码并转换为JSON对象,然后在应用程序中使用它。问题是,在尝试读取此数据时,内存中出现异常
该应用程序需要脱机工作,因此我需要下载完整数据
代码如下:
String localPath = getApplicationContext().getFilesDir().getPath().toString() ;
String key = "dataFile.txt" ;
StringBuilder text = new StringBuilder();
File file=new File(localPath+"/"+ key);
byte fileContent[] = new byte[3000];
try ( FileInputStream fin = new FileInputStream(file)) {
while(fin.read(fileContent) >= 0) {
byte[] data = Base64.decode(fileContent, Base64.DEFAULT);
try {
text.append(new String(data, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
obj = new JSONObject(text.toString());
}catch (Exception e){
e.printStackTrace();
}
如何读取此类文件?您试图通过读取文件、迭代文件并将每一行附加到文本中,将整个文件读取到文本对象中。您可以使用文本
对象创建JSONObject
,该对象仅在最后一步中对应用程序有用
在这里,当代码到达行obj=newJSONObject(text.toString())时
您已经用几乎与输入文件大小相同的大小填充了堆,因为这个完整的文件以test
对象的形式存在于内存中。然后将该text
对象设置为JSONObject
您可以采取以下措施来消除此问题:
使用BufferedReader
分块读取文件(可选)。使用read()
可能有点慢,最好有一个缓冲区
迭代该文件,并将条目成批地放入1000
或10000
的text
对象中
从text
中准备JSONObject
并将其附加到obj
中
在处理下一批之前,清除文本
对象,然后重复整个过程
通过这样做,您只读取了内存中文件的一小部分,并且text
对象充当缓冲区,只消耗了少量内存
以下是示例代码段:
int counter = 0;
String temp = null;
final int BATCH_SIZE = 1000;
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
while ((temp = br.readLine()) != null) {
text.append(temp);
++counter;
/* Process In Batches */
if(counter % BATCH_SIZE == 0) {
/* Prepare & Append JSON Objects */
obj = prepareAppendJSON(text.toString(), obj);
/* Clear text */
text.setLength(0);
}
}
/* Last Iteration */
obj = prepareAppendJSON(text, obj);
text = new StringBuilder();
} catch (IOException ex) {
ex.printStackTrace();
}
您唯一的选择是使用JSON流媒体
,并对您感兴趣的事件做出反应
import org.codehaus.jackson.*;
.....
JsonParser parser = new JsonFactory().createJsonParser( yourFileInputStream );
parser.configure( Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true );
parser.configure( Feature.ALLOW_SINGLE_QUOTES, true );
// add more features
for( JsonToken token = parser.nextToken(); null != token; token = parser.nextToken() ){
switch( token ){
case FIELD_NAME:
doStuffWithName();
break;
case START_OBJECT:
doObjectStart();
break;
case END_OBJECT:
processObject();
break;
// other events
}
}
我在4.0设备上使用了上述代码,JSON文件大小为10 MB
另外,你需要先解码你原来的Base64文件。不确定是否可以在java.io.Stream
中动态执行。在最坏的情况下,将Base64文件解压成一个普通的json,然后使用上面的json流代码你首先解雇那些认为Base64编码的json是个好主意的人,然后改造服务器,将常规json交给你。生成的~110MB JSON字符串仍然太大,无法使用JSONObject
进行解析。如果您只需要一小部分数据,请使用流式JSON解析器(Gson、Jackson等)。谢谢!但是什么是prepareAppendJSON方法呢?它是一个自定义对象,您必须编写它来准备字符串中的JSONObject
,然后将其附加到给定的JSONObject
。