2016-04-29 88 views
1

我有一个巨大的数据,当它在TextZip类中输入时,它覆盖了RAM大约2GB的区域。我无法解决如何缩小这个区域。我应该在那个班上改变什么?在java中压缩和解压缩时提供速度和小区域的任何替代方法或技术? 这里是我的类,它的名字是TextZip.java ==>如何在java中压缩和解压缩时使用小区域?

https://gist.github.com/anonymous/bd72fee48e1c3f8812ece187080e452e

问候。

+0

什么**巨大的数据**确实意味着什么?这是否意味着你分别传递了非常长的字符串作为'compress()'和'decompress()'方法的输入参数? – flaz14

+0

3627829字节被压缩。当它解压缩它变成129531542字节。它覆盖RAM中的2 GB区域。有时会抛出“OutOfMemory”错误。 TextZip类提供的替代方案可以覆盖RAM上的小区域? –

回答

0

TextZipByteArrayOutputStream积累未压缩的数据并动态增长。但它始终保存RAM中的所有数据。这就是为什么你会得到OutOfMemory错误。

考虑这样的事情(我省略了异常捕获为简洁起见):

... 
    OutputStream outputFile = new FileOutputStream("uncompressed"); // uncompressed data will be stored into file 
    byte[] smallBuf = new byte[1024000]; 
    ByteArrayOutputStream largeBuf = new ByteArrayOutputStream(); 
    while (!decompressor.finished()) { 
     int count = decompressor.inflate(smallBuf); 
     largeBuf.write(smallBuf, 0, count); 
     if (largeBuf.size() > 1024000 * 10) { // we already accumulated large chunk of data 
      largeBuf.writeTo(outputFile);  // so it's time to write it to disk 
      largeBuf.flush(); 
      largeBuf = new ByteArrayOutputStream(); // prepare for next large chunk 
     } 
    } 
    ... 

在上面的代码片段并不是所有的未压缩数据驻留在RAM(显然,2GB实在是太多了)。但是将每个小块数据写入文件(或发送到网络)效率不高(因为I/O开销)。因此,我们将未压缩的数据积累到大块(大约10兆字节)中,然后将这10MB写入磁盘。

一般来说,这是一个平衡的问题。将所有未压缩的数据保存在RAM中很快,但受可用内存量的限制。由于I/O,将未压缩的小数据块保存在RAM中很慢。为机器调整循环内部的条件。

+0

在java.util.concurrent.ThreadPoolExecutor中的$ Worker.runTask(ThreadPoolExecutor.java:895) \t在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:918) \t在java.lang.Thread中。运行(Thread.java:662) 引起:javax.xml.stream.XMLStreamException:[row,col]处的ParseError:[1,1] 消息:内容在prolog中不被允许。 \t at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:594) \t at com.thoughtworks.xstream.io.xml.StaxReader.pullNextEvent(StaxReader.java:58) \t ... 31更多它抛出这个错误。应该做什么? –

0
 public static synchronized String decompress(String compressedData) throws IOException { 
     // Create the decompressor and give it the data to compress 
//  Inflater decompressor = new Inflater(); 
     byte[] buffer = new Base64Encoder().decode(compressedData); 
// System.out.println("Created string from bytes by base 64 encoding"); 
     OutputStream outputFile = new FileOutputStream("unCompressed"); 
     byte[] smallBuf =new byte[1024]; 
     decompressor.setInput(buffer); 
     // Create an expandable byte array to hold the decompressed data 
     ByteArrayOutputStream largeBuf = new ByteArrayOutputStream(); 

     // Decompress the data 
     byte[] buf = new byte[10240]; 
     while (!decompressor.finished()) { 

      try { 
       int count = decompressor.inflate(buf); 
       largeBuf.write(smallBuf, 0, count); 
       if (largeBuf.size()>10240*10) { 
        largeBuf.writeTo(outputFile); 
        largeBuf.flush(); 
        largeBuf=new ByteArrayOutputStream(); 
       } 
      } catch (DataFormatException e) { 
//     System.out.println("Exception " + e); 
      } 

     } 
     try { 
      largeBuf.close(); 
     } catch (IOException e) { 
     } 

     // Get the decompressed data 
     byte[] decompressedData = largeBuf.toByteArray(); 

     decompressor.reset(); 
//  decompressor.end(); 

     return new String(decompressedData); 
    } 

我重新设计了我的解压缩方法。这是真的吗?

+0

你可以在行动中检查它... – flaz14