0

URLEncoder.encode を使用して Base64 でエンコードされた文字列をエンコードしたいのですが、この文字列には画像が含まれており、任意のサイズ (1MB ~ 8MB) にすることができます。

String imageDataToUpload = URLEncoder.encode(temp, "UTF-8");

02-27 02:41:45.213: D/dalvikvm(18600): GC_FOR_ALLOC freed 1824K, 12% free 26452K/29831K, paused 161ms
02-27 02:41:45.213: I/dalvikvm-heap(18600): Forcing collection of SoftReferences for 2968580-byte allocation
02-27 02:41:45.383: D/dalvikvm(18600): GC_BEFORE_OOM freed 9K, 12% free 26443K/29831K, paused 138ms
02-27 02:41:45.383: E/dalvikvm-heap(18600): Out of memory on a 2968580-byte allocation.

私もこのことをチャンクで試しましたが、その後 StringBuffer.append が OutOfMemoryError を作成しました

private String encodeChunckByChunck(String str, final int chunkSize) {
    StringBuffer buffer = new StringBuffer();
    final int size = str.length();
    try {
        for (int i = 0; i < size; i += chunkSize) {
            Log.d("Encode", "..........inside loop");
            if (i + chunkSize < size) {
                Log.d("Encode", "..........full chunk");
                buffer.append(URLEncoder.encode(str.substring(i, i + chunkSize), "UTF-8"));
            } else {
                Log.d("Encode", "..........half chunk");
                buffer.append(URLEncoder.encode(str.substring(i, size), "UTF-8"));
            }
        }
    } catch (UnsupportedEncodingException e) {
        Log.d("Encode", "..........exception:" + e.getMessage());
        e.printStackTrace();
    }
    Log.d("Encode", "..........before returning function");
    return buffer.toString();
}
4

2 に答える 2

0

(他の人がすでに指摘しているように、私も同意します)それがメモリの問題であると仮定すると、私があなただったら、データの小さなチャンクでその場で URLEncoding を行うカスタム OutputStream を実装します。

次のようになります (部分的なコードです。コンパイルするには、コードを入力する必要があります)。

public static class UrlEncOutputStream extends FileOutputStream {

    /* Implement constructors here */

    @Override
    public void write (byte [] b, int off, int len)  throws IOException {
            String s = StringUtils.newStringUsAscii(b);
            super.write(URLEncoder.encode(s, "UTF-8").getBytes());
    }

    /* Implement write(byte [] b) and write(int b) in similar fashion */
}

Tomasz Nurkiewiczがここに投稿した encode() メソッドを使用して、(ユース ケースに応じて) ファイル全体を一度にメモリにロードすることを回避することもできます。

public void encode(File file, OutputStream base64OutputStream) {
  InputStream is = new FileInputStream(file);
  OutputStream out = new Base64OutputStream(base64OutputStream)
  IOUtils.copy(is, out);
  is.close();
  out.close();
}

これですべてが整ったので、それを呼び出すことができます:

UrlEncOutputStream out = new UrlEncOutputStream("OUT.txt");
encode(new File("SOURCE.IMG"), out);

お役に立てれば!


編集:このコードを機能させるには、クラスパスに commons-codec と commons-io が必要です。

于 2013-02-26T22:25:57.153 に答える
0

メモリに保存する代わりに、ファイルに少しずつ書き込むことはできますか? それ以外の場合は、アプリの他の場所で使用するメモリを減らします (いくつかの大きな変数を解放します)。

于 2013-02-26T22:04:48.790 に答える