簡體   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