2012-06-17 61 views
6

我用我的ByteArray转换为字符串下面的代码:将ByteArray转换为字符串时发生OutOfMemory异常?

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

,但我得到以下异常时的ByteArray足够大。

是否有任何其他方式将ByteArray转换为字符串而不会发生内存异常?

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

除了它是不明智的处理3MB的字符串。 –

+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。是真的吗?使用'string = string +((char)byteArray [x]);'? – breceivemail

+0

@breceivemail看到我的编辑,我改变了它,所以字节将使用Unicode转换。 – John

+0

在Unicode字符串中,当字节数组被分割时,我们有一些错误的数据转换。 – breceivemail

0

你过度分配内存 - 首先你解压基地64和该分配缓冲区,然后你解开并且在chutnks到BAOS(这是alocating和重新分配的内存块)写入和你再复制到串 - 难怪它耗尽内存。

尝试重写这个流媒体处理(有srteaming的base64 dcoding,以及gzip的解码器)

相关问题