1

Androidアプリにjsonで構成されるテキストファイルがあります。そのjsonを読んで解析する必要があります。ファイルサイズは21MB。次のコードを使用してファイルを読み取ります。

 StringBuilder stringBuilder = new StringBuilder();
 InputStream input = getAssets().open(filename);
 int size = input.available();
 byte[] buffer = new byte[size];
 byte[] tempBuffer = new byte[1024];
 int tempBufferIndex = 0;
 for(int i=0; i<size; i++){
    if(i == 0){
        tempBuffer[tempBufferIndex] = buffer[i];
    }else{
        int mod = 1024 % i;
        if(mod == 0){
            input.read(tempBuffer);
            stringBuilder.append(new String(tempBuffer));
            tempBufferIndex = 0;
        }
        tempBuffer[tempBufferIndex] = buffer[i];
    }
}
input.close();

サイズ int は実際には 20949874 です。ループが完了した後、for ループの範囲を変更しても、stringBuilder の長さは常に 11264 です。ループを使用せずに InputStream から 1 つの文字列を作成しようとしましたが、常に OutOfMemoryError Exception が発生します。また、ログに「20949890 バイトの割り当てでヒープ (フラグメント ケース) を 26.668MB に拡張」というメッセージが表示されます。ここで検索し、さまざまな解決策を試しましたが、うまくいきませんでした。この問題をどのように解決すればよいでしょうか。前もって感謝します。

4

2 に答える 2

2

ファイルをいくつかの部分に分割してみることができます。したがって、処理中にアプリがメモリ不足にならないことを願っています。

マニフェストで「largeHeap」フラグを使用することも検討する必要があります ( http://developer.android.com/guide/topics/manifest/application-element.htmlを参照) 。

あなたのファイルはわかりませんが、より小さな JSON タグを使用すると、ストレージも削減できる可能性があります。

于 2014-12-01T14:58:51.050 に答える
2

大きな json ファイルの場合は、DOM ではなく SAX パーサーを使用する必要があります。たとえばJsonReader

DOM (「ドキュメント オブジェクト モデル」) はコンテンツ全体をメモリにロードし、開発者が必要に応じてデータをクエリできるようにします。 SAXはデータをストリームとして表示します。開発者は、必要なデータの断片が表示されるのを待ち、必要な部分だけを保存します。DOM は使いやすいと考えられていますが、SAX ははるかに少ないメモリを使用します。

于 2014-12-01T14:51:17.287 に答える