繁体   English   中英

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

[英]Reading internal storage file is taking too much time in Android

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

如果我在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;
}

我也在 while loop添加了一个警报,但我看不到任何警报消息。 我什至还没有看到Exception消息。

所以可能有两个问题。

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

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

更新1:

如果假设我无法在 Java 本机代码中读取如此大的文件,那么有什么方法可以从 WebView JavaScript 代码中读取内部存储的 Android 文件?

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

申请要求

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

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

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

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

  2. 一次读取一个文件,然后将这些行重新拼接在一起是不必要的。 它会产生不必要的垃圾。 额外的垃圾意味着 GC 需要做更多的工作,这会减慢您的速度。 如果行很长,则使用内部StringBuilder构建每行会增加性能“命中”。

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

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

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

  4. 寻找使用现有标准 Java 库的方法; Files.copyByteArrayOutputStream ,或Files.readAllBytes

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

  6. 不要在可以被调用数百万次的循环中间放置跟踪打印(我认为这就是alert ......)。 (呸!)


1 - 一旦你了解他们,解析器就会很高兴:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM