Java 在Android中读取内部存储文件花费了太多时间
我有大约20MB的大型JSON数据(我使用Java 在Android中读取内部存储文件花费了太多时间,java,android,json,Java,Android,Json,我有大约20MB的大型JSON数据(我使用JSON.stringify 来自JavaScript代码)。我正在将这个JSON数据写入Android设备上的一个内部存储文件,稍后再读取。因此,当我阅读文件时,它占用了太多的时间,我不知道它是否在阅读。还有一件事我只需要在主线程中阅读 如果我在WriteFile方法中传递数据值“helloworld”,那么下面的代码可以正常工作,但在使用大型JSON时失败 public String ReadFile() { StringBuffer tex
JSON.stringify
来自JavaScript代码)。我正在将这个JSON数据写入Android设备上的一个内部存储文件,稍后再读取。因此,当我阅读文件时,它占用了太多的时间,我不知道它是否在阅读。还有一件事我只需要在主线程中阅读 如果我在
WriteFile
方法中传递数据值“helloworld”,那么下面的代码可以正常工作,但在使用大型JSON时失败
public String ReadFile()
{
StringBuffer text = new StringBuffer();
String FILE_NAME = "file.txt";
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(openFileInput(FILE_NAME)));
String line;
int count = 0;
while ((line = bReader.readLine()) != null) {
text.append(line + "\n");
alert("Reading File: " + ++count);
}
}
catch (Exception e) {
alert(e.toString());
}
return text.toString();
}
public String WriteFile(String data)
{
String FILE_NAME = "file.txt";
String result = "";
try {
FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
fos.write(data.toString().getBytes());
result = "Success";
fos.close();
}
catch (Exception e) {
e.printStackTrace();
result="Error";
}
return result;
}
我在while循环中也添加了一个警报,但我看不到任何警报消息。我甚至没有看到异常
消息
所以可能有两个问题
写入文件时出错(但我不知道如何验证?因为我不认为有任何方法可以查看内部存储文件)
我的代码读错了
更新1:
如果我不能用Java本机代码读取这么大的文件,那么有没有办法从WebView JavaScript代码中读取内部存储的Android文件
============================================================================
应用要求
我有一个Android应用程序,其中有一个WebView。我已经将完整的javascript代码(js和HTML文件)复制到应用程序的资产文件夹中。我正在从java本机代码写入文件,并从java本机代码读取。我在应用程序启动时从服务器获取所有数据。我的客户有一个非常缓慢的互联网连接和它的断开多次。因此,他们希望该应用程序在脱机模式下运行。这意味着应用程序将在发布时获取所有数据,我们将把数据存储在某个地方,然后在整个应用程序中读取数据。如果用户再次启动应用程序,它将获得旧的现有数据。实际上,这些数据非常大,所以我将其存储到内部存储文件中。首先,要真正确定代码耗时的唯一方法是对其进行分析。我们不能为你这样做
但以下是一些与代码相关的性能提示:
除非确实需要,否则不要将整个20MB JSON文件读入Java堆/RAM内存。(我发现很难理解您为什么这样做。例如,典型的JSON解析器可能会直接从文件读取输入。或者,如果您正在读取输入,以便可以将其发送到HTTP连接另一端的客户端,那么您应该能够流式传输数据。)
一次读取一行文件,然后将这些行缝合在一起是不必要的。它会产生不必要的垃圾。额外的垃圾意味着GC要做更多的工作,这会减慢您的速度。如果行很长,则可以使用内部StringBuilder
构建每一行,从而提高性能
读取回收的char[]
,然后将char[]
内容追加到StringBuilder
将比追加行更快
您的StringBuilder
将重复“增长”其支持字符数组,以便在追加字符时容纳这些字符。这会产生垃圾并导致不必要的复制。(实现通常会以指数方式“增长”阵列,以避免出现O(N^2)
行为。但是,扩展仍会影响性能,并可能导致高达实际所需峰值内存使用量的3倍。)
避免这种情况的一种方法是获得要添加的字符数的初始估计值,并相应地设置StringBuilder
“容量”。您可以根据文件大小估计字符数。(这取决于编码。)
寻找一种使用现有标准Java库的方法;e、 g.文件。通过tearrayoutputstream复制和或文件。readAllBytes
寻找现有的第三方库方法;e、 Apache Commons IO有一个IOUtils.toString(Reader)
方法。他们很可能已经花了很多时间来研究如何有效地做到这一点。重用一个设计良好、维护良好的库可能会节省您的时间
不要把痕迹打印出来(我假设是<代码>警报>代码>……)在一个可以被称为上百万次的循环的中间。(呸!)
1-一旦你了解了解析器,他们会很高兴:-)“我只需要在主线程中读一件事”——不,你不需要。除此之外,我还希望您的代码经常崩溃,出现OutOfMemoryError
。您没有大量大缓冲区的堆空间,这段代码涉及大量大缓冲区:您要写入的20MB字符串,该字符串作为字节[]
的副本,以及每行递增的缓冲区。这假设您修复了WriteFile()
中的错误,您正在编写一个空的StringBuffer
,而不是实际的文本(数据
未使用)。“因为我认为没有任何方法查看内部存储文件”——请使用Android Studio中的模拟器和设备文件浏览器。还要注意的是,StringBuffer
的性能比StringBuilder
差,正如在@commonware中所述,很抱歉这是打字错误。我更正了代码,它的数据
不是文本
@commonware我不能在Android设备上查看文件吗?@commonware那么我现在如何修复ReadFile方法?