Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Deflater.deflate和小输出缓冲区_Java_Deflate - Fatal编程技术网

Java Deflater.deflate和小输出缓冲区

Java Deflater.deflate和小输出缓冲区,java,deflate,Java,Deflate,我看到了一种奇怪的情况,使用Java8U45的小输出缓冲区以及使用小输出缓冲区时的方法 (我正在编写一些与WebSocket即将推出的permessagedeflate扩展相关的低级网络代码,因此小型缓冲区对我来说是现实) 示例代码: 包装放气; 导入java.nio.charset.StandardCharset; 导入java.util.zip.Deflater; 公共类DeflaterSmallBufferBug { 公共静态void main(字符串[]args) { 布尔nowrap=

我看到了一种奇怪的情况,使用Java8U45的小输出缓冲区以及使用小输出缓冲区时的方法

(我正在编写一些与WebSocket即将推出的
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。