所以.net没有ZlibStream所以我试图使用.net确实拥有的DeflateStream来实现我自己的。 DeflateStream
显然也不支持使用字典,因此我也会在ZlibStream
中跳过它。
写作效果很好,但我的Read方法有问题 这是我的Read方法:
public override int Read(byte[] buffer, int offset, int count)
{
EnsureDecompressionMode();
if (!_readHeader)
{
// read the header (CMF|FLG|optional DIC)
_readHeader = true;
}
var res = _deflate.Read(buffer, offset, count);
if (res == 0) // EOF
{
// read adler32 checksum
BaseStream.ReadFully(_scratch, 0, 4);
var checksum = (uint)_scratch[0] << 24 |
(uint)_scratch[1] << 16 |
(uint)_scratch[2] << 8 |
(uint)_scratch[3];
if (checksum != _adler32.Checksum)
{
throw new ZlibException("Invalid checksum");
}
}
else
{
_adler32.CalculateChecksum(buffer, offset, res);
}
return res;
}
其中:
_scratch
是用作临时缓冲区的byte[4]
_deflate
是DeflateStream
。 Zlib的格式为CMF|FLG|optional DICT|compressed data|adler32|
。所以我需要一种方法来在达到adler32
时停止阅读。最初,我认为DeflateStream
会在完成后返回EOF,但事实证明它会读取到底层流的EOF
。所以它也会像adler32
一样读取它的压缩数据。因此,当我尝试从adler32
块内的BaseStream中读取if
时,会抛出EOF异常。
那么我如何让DeflateStream
停止阅读adler32
,就像它的压缩数据一样,而不是那里的EOF或做同等的事情,以便我可以从adler32
读取<Input value="{applicationModel>/propertyName}" editable="{viewModel>/editable}"/>
没有压缩的BaseStream?
答案 0 :(得分:0)
由于文件大小固定,您只需停留在base.Length - typeof(int)
?必要时调整读缓冲区,然后读取未压缩的校验和。
喜欢:
public override int Read(byte[] buffer, int offset, int count)
{
// read header...
int res = -1;
if (base.Position + count - offset > base.Length)
{
// EOF, skip the last four bytes (adler32) and read them without decompressing
res = _deflate.Read(buffer, offset, count - sizeof(int));
}
else
{
res = _deflate.Read(buffer, offset, count);
}
// continue processing the data
}
未经过测试