gpt4 book ai didi

java - 使用 deflater 压缩/解压缩字符串

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:34:34 26 4
gpt4 key购买 nike

我想压缩/解压缩和序列化/反序列化字符串内容。我正在使用以下两个静态函数。

/**
* Compress data based on the {@link Deflater}.
*
* @param pToCompress
* input byte-array
* @return compressed byte-array
* @throws NullPointerException
* if {@code pToCompress} is {@code null}
*/
public static byte[] compress(@Nonnull final byte[] pToCompress) {
checkNotNull(pToCompress);

// Compressed result.
byte[] compressed = new byte[] {};

// Create the compressor.
final Deflater compressor = new Deflater();
compressor.setLevel(Deflater.BEST_SPEED);

// Give the compressor the data to compress.
compressor.setInput(pToCompress);
compressor.finish();

/*
* Create an expandable byte array to hold the compressed data.
* You cannot use an array that's the same size as the orginal because
* there is no guarantee that the compressed data will be smaller than
* the uncompressed data.
*/
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(pToCompress.length)) {
// Compress the data.
final byte[] buf = new byte[1024];
while (!compressor.finished()) {
final int count = compressor.deflate(buf);
bos.write(buf, 0, count);
}

// Get the compressed data.
compressed = bos.toByteArray();
} catch (final IOException e) {
LOGWRAPPER.error(e.getMessage(), e);
throw new RuntimeException(e);
}


return compressed;
}

/**
* Decompress data based on the {@link Inflater}.
*
* @param pCompressed
* input string
* @return compressed byte-array
* @throws NullPointerException
* if {@code pCompressed} is {@code null}
*/
public static byte[] decompress(@Nonnull final byte[] pCompressed) {
checkNotNull(pCompressed);

// Create the decompressor and give it the data to compress.
final Inflater decompressor = new Inflater();
decompressor.setInput(pCompressed);

byte[] decompressed = new byte[] {};

// Create an expandable byte array to hold the decompressed data.
try (final ByteArrayOutputStream bos = new ByteArrayOutputStream(pCompressed.length)) {
// Decompress the data.
final byte[] buf = new byte[1024];
while (!decompressor.finished()) {
try {
final int count = decompressor.inflate(buf);
bos.write(buf, 0, count);
} catch (final DataFormatException e) {
LOGWRAPPER.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
// Get the decompressed data.
decompressed = bos.toByteArray();
} catch (final IOException e) {
LOGWRAPPER.error(e.getMessage(), e);
}

return decompressed;
}

然而,与未压缩的值相比,即使我正在缓存解压缩的结果,它也慢了几个数量级,并且只有在真正需要内容时才解压缩值。

也就是说,它用于类似于 DOM 的可持久树结构和 XPath 查询,它们强制对字符串值进行解压,如果不是更慢的话,速度大约是 50 倍(不是真正的基准测试,只是执行单元测试)。我的笔记本电脑甚至在一些单元测试后死机(每次,检查大约 5 次),因为 Eclipse 由于磁盘 I/O 和其他原因不再响应。我什至将压缩级别设置为 Deflater.BEST_SPEED,而其他压缩级别可能更好,也许我提供了一个可以为 resources 设置的配置选项参数.也许我搞砸了,因为我以前没有使用过放气器。我什至只压缩字符串长度大于 10 的内容。

编辑:在考虑将 Deflater 实例化提取到静态字段之后,创建 deflater 和 inflater 的实例似乎非常昂贵,因为性能瓶颈已经消失,也许没有微基准测试或类似的我可以没有看到任何性能损失 :-) 我只是在使用新输入之前重置放气器/充气器。

最佳答案

您如何考虑使用 Gzip 等更高级别的 API。

这里是一个压缩的例子:

public static byte[] compressToByte(final String data, final String encoding)
throws IOException
{
if (data == null || data.length == 0)
{
return null;
}
else
{
byte[] bytes = data.getBytes(encoding);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream os = new GZIPOutputStream(baos);
os.write(bytes, 0, bytes.length);
os.close();
byte[] result = baos.toByteArray();
return result;
}
}

这里是一个解压的例子:

public static String unCompressString(final byte[] data, final String encoding)
throws IOException
{
if (data == null || data.length == 0)
{
return null;
}
else
{
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
GZIPInputStream is = new GZIPInputStream(bais);
byte[] tmp = new byte[256];
while (true)
{
int r = is.read(tmp);
if (r < 0)
{
break;
}
buffer.write(tmp, 0, r);
}
is.close();

byte[] content = buffer.toByteArray();
return new String(content, 0, content.length, encoding);
}
}

我们由此获得了非常好的性能和压缩率。

zip api 也是一个选项。

关于java - 使用 deflater 压缩/解压缩字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9542987/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com