在Android中读取内部存储文件需要花费太多时间

时间:2018-08-20 11:14:52

标签: java android json

我有大约20 MB的大型JSON数据(我使用JSON.stringify创建此数据  来自JavaScript代码)。我正在将此JSON数据写入Android设备上的内部存储文件中,并在以后读取。因此,当我读取文件时,它花费了太多时间,我不知道是否读取了文件。我只需要在Main线程中阅读一件事。

如果我在WriteFile方法中传递数据值“ Hello World”,则下面的代码可以正常工作,但是使用大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;
}

我也同时在loop中添加了一个警报,但是我看不到任何警报消息。我什至都没有看到Exception消息。

所以可能有两个问题。

  1. 写文件时出了点问题(但是我不知道该如何验证?因为我认为没有任何方法可以查看内部存储文件)。

  2. 我的阅读代码有问题。

更新1:

如果说我无法用Java本机代码读取这么大的文件,那么有什么方法可以从WebView JavaScript代码读取内部存储Android文件吗?

================================================ ===========================

申请要求

我有一个Android应用程序,其中有一个WebView。我已将完整的javascript代码(js和HTML文件)复制到了应用程序的Assets文件夹中。我正在从Java本机代码写入文件,并从Java本机代码读取。我正在启动应用时从服务器获取所有数据。我的客户的互联网连接速度非常慢,并且断开了很多次。因此,他们希望该应用程序以脱机模式运行。意味着应用程序将在启动时获取所有数据,我们会将其存储在某个地方,然后在整个应用程序中读取它们。如果用户再次启动该应用程序,它将获取旧的现有数据。实际上,这些数据非常大,因此我将其存储到内部存储文件中。

1 个答案:

答案 0 :(得分:1)

首先,要真正确定为什么代码要花很长时间的唯一方法是对其进行概要分析。我们不能为您做到这一点。

但这是与您的代码相关的一些性能提示:

  1. 除非确实需要,否则不要将整个20MB JSON文件读入Java堆/ RAM内存。 (我很难理解为什么要这么做。例如,典型的JSON解析器会很高兴地 1 直接从文件中读取输入。或者,如果您正在读取此内容,则可以发送该文件到HTTP连接另一端的客户端,您应该能够流式传输数据。)

  2. 一次读取一个文件,然后将这些行缝合在一起是不必要的。它产生不必要的垃圾。多余的垃圾意味着GC需要做更多的工作,这会使您放慢速度。如果行很长,则可以使用内部StringBuilder来构建每行,从而增加了性能。

    读取回收的char[],然后将char[]内容附加到StringBuilder会比附加行更快。

  3. 您的StringBuilder将反复“增长”其支持的字符数组,以在您追加字符时容纳它们。这会产生垃圾并导致不必要的复制。 (实现通常以指数方式“增长”阵列以避免O(N^2)行为。但是,扩展仍然会影响性能,并且可能导致峰值内存使用量是实际所需的三倍。)

    避免这种情况的一种方法是对要添加的字符数进行初步估计,并相应地设置StringBuilder“容量”。您可能可以根据文件大小来估计字符数。 (取决于编码。)

  4. 寻找一种使用现有标准Java库实现此目标的方法;例如Files.copyByteArrayOutputStream,或Files.readAllBytes

  5. 寻找现有的第三方库方法;例如Apache Commons IO具有IOUtils.toString(Reader)方法。他们可能会花很多时间弄清楚如何有效地做到这一点。重用精心设计,维护良好的库可能会节省您的时间。

  6. 不要在可能被调用数百万次的循环的中间放置跟踪打印(我假设是alert是……)。 (Du!)


1-一旦您了解语法分析器,他们就会很高兴:-)