2012-06-17 2 views
6

Я использую следующий код для преобразования моего ByteArray в строку:Исключение OutOfMemory при преобразовании ByteArray в String?

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

Но я получаю следующее исключение при ByteArray достаточно велик.

Есть ли другой способ преобразования ByteArray в String без исключения из памяти?

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

Какой размер будет строка? Если он очень большой, вы уверены, что хотите иметь его как одну строку? –

+0

Знаете ли вы размер ByteArray, который вызывает исключение? Можно ли проверить размер ByteArray до преобразования, и если над этим критическим размером, возможно, конвертируйте на более мелкие шаги? – Kerry

+0

Размер ByteArray составляет 3663125 байт – breceivemail

ответ

0

После сниппета поможет you.Try читать куски

   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

За исключением того, что нецелесообразно обрабатывать строку 3 МБ. –

+0

Что такое ** в **? – breceivemail

+0

Моя строка - Unicode. Верно ли это использовать 'sb.append ((char) byteRead);'? – breceivemail

0

я бы разбить его на как 1000 строк полукокса в время. 3663125 байт - большая часть памяти, особенно для Android.

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(); 

Это разрушит его для вас, вы можете изменить 1000, чтобы быть тем, что хотите, если это слишком мало.

+0

Моя строка - Unicode. Является ли это истинным ti использовать 'string = string + ((char) byteArray [x]);'? – breceivemail

+0

@breceivemail см. Мое редактирование, я изменил его, чтобы байты были преобразованы с помощью юникода. – John

+0

В строке Unicode у нас есть некорректное преобразование данных при распаде byteArray. – breceivemail

0

Вы выделяете память чрезмерно - сначала вы распаковываете базу 64 и выделяете буфер для этого, затем вы распаковываете ее и записываете в chutnks в BAOS (который выделяет и перераспределяет куски памяти), и вы копируете его снова в строку - неудивительно, что у него заканчивается память.

Попытка переписать это процесс потокового (там srteaming base64 dcoding, а также GZip декодер)

Смежные вопросы