我的DeflaterOutputStream/InputStream代码损坏了数据



我有一个简单的测试用例,它无法压缩数据流。我生成一些随机字节的byte[],通过DeflaterOutputStreamflush()流对其进行压缩,然后反转这些操作以检索原始数组。在字节505,重建的流开始完全由0x00字节组成,我不明白为什么:

//
// create some random bytes
//
Random rng = new Random();
int len = 5000;
byte[] data = new byte[len];
for (int i = 0; i < len; ++i)
data[i] = (byte) rng.nextInt(0xff);
//
// write to byte[] via a deflater stream
//
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream os = new DeflaterOutputStream(baos, true);
os.write(data);
os.flush();
//
// read back into byte[] via an inflater stream
//
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
InflaterInputStream is = new InflaterInputStream(bais);
byte[] readbytes = new byte[len];
is.read(readbytes);
//
// check they match (they don't, at byte 505)
//
for (int i = 0; i < len; ++i)
if (data[i] != readbytes[i])
throw new RuntimeException("Mismatch at position " + i);

源数组中的内容似乎并不重要,它总是在505位置发生故障。

以下是两个byte[]阵列在不同区域周围的样子:

?m·g··gWNLErZ···,··-··=·;n=··F?···13·{·rw·······`3···f····{/····t·1·WK$·······WZ······x
?m·g··gWNLErZ···,··-····································································
^byte 505

从那时起,所有那些不可打印的字符都是0x00。为什么会发生这种情况?我觉得我一定误解了通货紧缩/通货膨胀流如何运作的一些基本原理。这里的真实用例是网络上的流,我认为通过将Deflate/Ampure流插入,我可以很容易地提高其性能

当我测试它时,is.read(readBytes)返回505,即读取的字节长度。其他单参数数组流方法返回void并保证整个数组是读或写的,但is.read()是不同的API,需要检查实际读取的字节数。

ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
System.err.println( "bais size = " + bais.available() );
InflaterInputStream is = new InflaterInputStream(bais);
byte[] readbytes = new byte[len];
System.err.println( "read = " + is.read(readbytes) );  // 505

这运行时没有为我抛出错误:

ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
System.err.println( "bais size = " + bais.available() );
InflaterInputStream is = new InflaterInputStream(bais);
byte[] readbytes = new byte[len];
for( int total = 0, result = 0; (result = is.read(readbytes, total, len-total )) != -1; )
{
total += result;
System.err.println( "reading : " + total );
if( total == len ) break;
}

最新更新