Java Deflater.deflate和小输出缓冲区
我看到了一种奇怪的情况,使用Java8U45的小输出缓冲区以及使用小输出缓冲区时的方法 (我正在编写一些与WebSocket即将推出的Java Deflater.deflate和小输出缓冲区,java,deflate,Java,Deflate,我看到了一种奇怪的情况,使用Java8U45的小输出缓冲区以及使用小输出缓冲区时的方法 (我正在编写一些与WebSocket即将推出的permessagedeflate扩展相关的低级网络代码,因此小型缓冲区对我来说是现实) 示例代码: 包装放气; 导入java.nio.charset.StandardCharset; 导入java.util.zip.Deflater; 公共类DeflaterSmallBufferBug { 公共静态void main(字符串[]args) { 布尔nowrap=
permessagedeflate
扩展相关的低级网络代码,因此小型缓冲区对我来说是现实)
示例代码:
包装放气;
导入java.nio.charset.StandardCharset;
导入java.util.zip.Deflater;
公共类DeflaterSmallBufferBug
{
公共静态void main(字符串[]args)
{
布尔nowrap=true;
Deflater Deflater=新的Deflater(Deflater.DEFAULT\u COMPRESSION,nowrap);
byte[]input=“Hello”.getBytes(标准字符集.UTF_8);
System.out.printf(“输入为%,d字节-%s%n”,input.length,getHex(input,0,input.length));
deflater.setInput(输入);
字节[]输出=新字节[input.length];
//从无限循环中挣脱出来
int maxloops=10;
//压缩数据
while(最大循环-->0)
{
int compressed=deflater.deflate(输出,0,输出.长度,deflater.SYNC_FLUSH);
System.out.printf(“压缩,d字节-%s%n”,压缩,getHex(输出,0,压缩));
if(压缩<输出长度)
{
System.out.printf(“压缩成功”);
返回;
}
}
System.out.printf(“已退出压缩(maxloops左%d)%n”,maxloops);
}
私有静态字符串getHex(字节[]buf,int offset,int len)
{
StringBuilder十六进制=新的StringBuilder();
十六进制追加('[');
对于(int i=偏移量;i<(偏移量+长度);i++)
{
如果(i>偏移)
{
十六进制附加(“”);
}
hex.append(String.format(“%02X”,buf[i]);
}
十六进制追加(']');
返回hex.toString();
}
}
在上面的例子中,我试图使用长度为5字节的输出缓冲区为输入“Hello”
生成压缩字节
我将假设以下结果字节:
缓冲区1[F248 CD C9 C9]
缓冲器2[07 00 FF]
缓冲区3[FF]
也就是说
[F248 CD C9 C9 07 00]这是一个zlib“功能”,记录在zlib.h中:
如果是Z_FULL_FLUSH或Z_SYNC_FLUSH,请确保
avail_out大于6,以避免由于以下原因而重复冲洗标记
返回时avail_out==0
正在发生的是,使用Z_SYNC_FLUSH
调用deflate()
时,每次都会插入一个五字节的FLUSH标记。由于没有提供足够的输出空间来获取标记,因此再次调用以获取更多输出,但同时要求它插入另一个刷新标记
您应该做的是使用Z_SYNC_FLUSH
调用deflate()
一次,然后使用额外的deflate()
调用获取所有可用的输出,如果需要,使用Z_NO_FLUSH
(或Java中的NO_FLUSH
)!马克·阿德勒回答了我的问题,很难得到比这个更权威的答案。:-)我想我应该向Oracle提交一个apidoc bug,以便将这个小贴士添加到Deflater文档中。知道似乎很有用。它应该被视为一个“bug”,对吗?zlib为什么这么做?保存国旗?也许吧。这取决于你期望这样的电话意味着什么和做什么。当您使用Z_SYNC_FLUSH
或Z_FULL_FLUSH
调用deflate()
时,您请求deflate在流中插入一个空的存储块。那么,它不应该为每个这样的调用插入一个空的存储块吗?或者,deflate可以忽略后续插入标记的请求,直到您使用了包含第一个请求的输出。不管怎样,你都可以说这是一个bug。