2016-09-20 18 views
1

私はのAndroidアプリケーションを開発しています。これは、AndroidのCipher Classを使用して大きなファイルを復号化しています。Cipher.dofinal()のメモリ不足エラー

コード:

private byte[] decrypt_chunk(byte[] data, ByteString chunk_encryption_key) { 
     SecretKeySpec skeySpec = new SecretKeySpec(chunk_encryption_key.toByteArray(), 1, 16, "AES"); 
     Cipher cipher; 
     byte[] decrypted = new byte[0]; 
     try { 
      cipher = Cipher.getInstance("AES/CFB/NoPadding"); 

      cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(getIV(0))); 

      decrypted = cipher.doFinal(data); 

     } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
      e.printStackTrace(); 
     } catch (InvalidKeyException e) { 
      e.printStackTrace(); 
     } catch (InvalidAlgorithmParameterException e) { 
      e.printStackTrace(); 
     } catch (ShortBufferException e) { 
      e.printStackTrace(); 
     } 

     return decrypted; 
    } 

大きなファイルを復号化しながら、私は"のOutOfMemory"エラーを取得しています。

I以下の質問があります。

  1. 現在のコードで何chanegs OOMエラーを修正することができますか?

  2. Cipher.update()は問題を解決するのに役立ちますか?はいの場合、それを実装する方法は?

ありがとうございます。

+0

どのようにデータを読み込みますか? –

+0

私はオンラインサーバーからデータを読み取り、それをbyte []に​​格納しています。 –

+0

ファイル全体を一度に読み込むことはできません。一度にブロックをロードする必要があります。 –

答えて

2

Cipher.update()メソッドを使用する方法もあります。

あなたの場合は、代わりにCipherOutputStreamを使用することをおすすめします。私はあなたがサーバーからデータを取得するためのInputStreamとファイルにデータを保存するためのFileOutputStreamを持っていると仮定します。

FileOutputStream fout = ... 
CipherOutputStream cout = new CipherOutputStream(fout, cipher); 

今すぐcoutの代わりfoutを引き続き使用すると、あなたがそれに書き込むすべてが自動的に暗号化されます。CipherOutputStreamを使用して

は単に「ラップそれを」たFileOutputStreamを中心に、非常に単純です。

+0

ありがとうございました。しかし、私は、サーバーからバイトを読み取っている間にいくつかの操作を実行する必要があるため、データをbyte []として格納しています。 –

+0

代わりに 'ChipherInputStream'を使用します(読み込み中に暗号化/復号化)。これは同じ方法で動作しますが、Webからファイルをロードするときに得られるようなInputStreamをラップします。 – Robert