我的 DeflaterOutputStream/InputStream 代码损坏数据
My DeflaterOutputStream/InputStream code corrupting data
我有一个无法压缩数据流的简单测试用例。我生成一些随机字节的 byte[]
,通过 DeflaterOutputStream
、flush()
流压缩它,然后反转这些操作以检索原始数组。在字节 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/Inflate 流如何工作的基本知识。这里的真实用例是网络上的流,我认为我可以通过将 Deflate/Inflate 流插入
来轻松提高性能
当我测试这个时,is.read(readBytes)
returns 505,读取的字节长度。其他 single-argument-array 流方法 return 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;
}
我有一个无法压缩数据流的简单测试用例。我生成一些随机字节的 byte[]
,通过 DeflaterOutputStream
、flush()
流压缩它,然后反转这些操作以检索原始数组。在字节 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/Inflate 流如何工作的基本知识。这里的真实用例是网络上的流,我认为我可以通过将 Deflate/Inflate 流插入
当我测试这个时,is.read(readBytes)
returns 505,读取的字节长度。其他 single-argument-array 流方法 return 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;
}