2012-06-17 26 views
6

używam następujący kod do konwersji mój ByteArray się wyrażenie:Wyjątek OutOfMemory w konwersji ByteArray na ciąg?

String sReturn = new String(byteArray, "UTF-8"); 

Ale pojawia się następujący wyjątek, gdy ByteArray jest wystarczająco duży.

Czy istnieje inny sposób konwertowania obiektu ByteArray na ciąg bez wyjątku braku pamięci?

06-17 12:27:37.594: E/dalvikvm(1617): Out of memory: Heap Size=30663KB, Allocated=22087KB, Bitmap Size=936KB, Limit=32768KB 
06-17 12:27:37.594: E/dalvikvm(1617): Extra info: Footprint=30663KB, Allowed Footprint=30663KB, Trimmed=616KB 
06-17 12:27:37.594: W/dalvikvm(1617): threadid=9: thread exiting with uncaught exception (group=0x4001d648) 
06-17 12:27:37.594: E/AndroidRuntime(1617): FATAL EXCEPTION: Thread-19 
06-17 12:27:37.594: E/AndroidRuntime(1617): java.lang.OutOfMemoryError: (Heap Size=30663KB, Allocated=22087KB, Bitmap Size=936KB) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at java.lang.String.<init>(String.java:422) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at java.lang.String.<init>(String.java:276) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.utils.Utilities.decompress(Utilities.java:389) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.utils.WebserviceResponse.getClearedResponse(WebserviceResponse.java:18) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.businessLayer.BoWebService.getDataForUpdate(BoWebService.java:216) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.ui.ActToolDataExchange.threadGetDataForFullUpdate(ActToolDataExchange.java:389) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.ui.ActToolDataExchange.access$9(ActToolDataExchange.java:380) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.ui.ActToolDataExchange$35.run(ActToolDataExchange.java:639) 
06-17 12:27:37.594: E/AndroidRuntime(1617):  at org.mabna.order.utils.Utilities$4.run(Utilities.java:924) 

UPDATE

public static String decompress(String zipText) throws IOException { 
    byte[] compressed = Base64.decode(zipText); 
    if (compressed.length > 4) { 
     GZIPInputStream gzipInputStream = new GZIPInputStream(
       new ByteArrayInputStream(compressed, 4, 
         compressed.length - 4)); 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     for (int value = 0; value != -1;) { 
      value = gzipInputStream.read(); 
      if (value != -1) { 
       baos.write(value); 
      } 
     } 
     gzipInputStream.close(); 
     baos.close(); 

     byte[] byteArray = baos.toByteArray(); 

     Log.i("toByteArray", String.valueOf(byteArray.length)); 

     String sReturn = new String(byteArray, "UTF-8"); 

     return sReturn; 
    } else { 
     return ""; 
    } 
} 



public static String decrypt(String encrypted, String password) 
     throws Exception { 

    byte[] encrypteddata = Base64.decode(encrypted); 

    byte[] bytes = decrypt(encrypteddata, password); 

    String result = new String(bytes, "UTF-8"); 

    return result; 
} 

public static byte[] decrypt(byte[] encrypted, String password) 
     throws Exception { 

    byte[] passwordKey = encodeDigest(password); 
    try { 
     aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION); 
    } catch (NoSuchAlgorithmException e) { 
     throw new Exception(
       "Decryption Exception: No such algorithm\r\n" + e 
         .toString()); 
    } catch (NoSuchPaddingException e) { 
     throw new Exception(
       "Decryption Exception: No such padding PKCS5\r\n" + e 
         .toString()); 
    } 
    secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM); 

    try { 
     aesCipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); 
    } catch (InvalidKeyException e) { 
     throw new Exception(
       "Decryption Exception: Invalid key\r\n" + e.toString()); 
    } catch (InvalidAlgorithmParameterException e) { 
     throw new Exception(
       "Decryption Exception: Invalid algorithm\r\n" + e 
         .toString()); 
    } 

    byte[] encryptedData; 
    try { 
     encryptedData = aesCipher.doFinal(encrypted); 
    } catch (IllegalBlockSizeException e) { 
     throw new Exception(
       "Decryption Exception: Illegal block size\r\n" + e 
         .toString()); 
    } catch (BadPaddingException e) { 
     throw new Exception(
       "Decryption Exception: Bad padding\r\n" + e 
         .toString()); 
    } 
    return encryptedData; 
} 
+1

Jaki rozmiar byłby ciąg? Jeśli jest bardzo duży, czy na pewno chcesz go mieć jako jeden ciąg? –

+0

Czy znasz rozmiar obiektu ByteArray, który powoduje wyrzucenie wyjątku? Czy możliwe byłoby sprawdzenie rozmiaru ByteArray przed konwersją i czy w przypadku tego krytycznego rozmiaru można dokonać konwersji w mniejszych krokach? – Kerry

+0

Rozmiar ByteArray to 3663125 Bytes – breceivemail

Odpowiedz

0

Poniższy urywek pomoże you.Try czytać na wyrywki

   StringBuilder sb=new StringBuilder(); 

      Log.v("abc","length : " + byteArray.length); 

      while (totalBytesRead < formDataLength) {  
       byteRead = in.read(dataBytes, totalBytesRead, formDataLength);  
       // byteRead = in.read(dataBytes);  
       //totalBytesRead += byteRead;  
       sb.append((char)byteRead); 
      }  

       String s=sb.toString(); 
+1

Z tym, że nie jest rozsądnie obsłużyć ciąg 3MB. –

+0

Co to jest ** w **? – breceivemail

+0

Mój ciąg to kod Unicode. Czy to prawda, że ​​używasz 'sb.append ((char) byteRead);'? – breceivemail

0

chciałbym złamać go na niczym ciągi char w 1000 czas. 3663125 bajtów to dużo pamięci, szczególnie dla Androida.

ArrayList<String> strings = new ArrayList<String>(); 
byte[] set = new byte[1000]; 
for(int x = 0, index = 0; x < byteArray.length;x++, index++) 
{ 
    set[index] = byteArray[x]; 
    if(index == 999) 
    { 
     strings.add(new String(set, "Unicode")); 
     index = 0; 
     if(byteArray.length - x < 1000) // shorten the set when there are less than 1000 bytes left 
      set = new byte[byteArray.length - x]; 
    } 
} 

strings.add(new String(set, "Unicode")); 

String stringArray[] = (String[])strings.toArray(); 

To rozbije to dla Ciebie, możesz zmienić 1000, aby być, co chcesz, jeśli to zbyt małe.

+0

Mój ciąg to kod Unicode. Czy to prawda, że ​​używa się 'string = string + ((char) byteArray [x]);'? – breceivemail

+0

@breceivemail zobacz moją edycję, zmieniłem ją, aby bajty były konwertowane przy użyciu Unicode. – John

+0

W łańcuchu Unicode mamy pewne złe konwersje danych, gdy dzielone jest byteArray. – breceivemail

0

Przydzielasz pamięć nadmiernie - najpierw rozpakuj bazę 64 i przydziel do niej bufor, następnie rozpakuj ją i pisz w chutnkach do BAOS (który alokuje i ponownie przydziela fragmenty pamięci) i kopiujesz go ponownie do ciągu znaków - nic dziwnego, że zabrakło mu pamięci.

Spróbuj przepisać to proces przesyłania strumieniowego (tam jest srteaming base64 dcoding, jak również dekoder gzip)