如何在java中提供压缩和解压缩时使用小区域



我有一个巨大的数据,当它进入TextZip类时,它覆盖了RAM中大约2GB的区域。我无法解决如何缩小那个区域。那节课我该换什么?在java中进行压缩和解压缩时,有没有提供速度和小面积的替代方案或技术?这是我的类,名称为TextZip.java==>

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

谨致问候。

TextZip类中,ByteArrayOutputStream积累未压缩的数据并动态增长。但它总是将所有数据保存在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中保留小块未压缩数据的速度较慢。为您的机器调整内循环条件。

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

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

最新更新