使用SharpZipLib的GZipInputStream编写未压缩的GZIP流时遇到问题。我似乎只能获得价值256字节的数据,而其余的数据不会被写入并置零。已检查压缩流(compressedSection),并且所有数据都存在(1500+字节)。减压过程的代码段如下:
int msiBuffer = 4096;
using (Stream msi = new MemoryStream(msiBuffer))
{
msi.Write(compressedSection, 0, compressedSection.Length);
msi.Position = 0;
int uncompressedIntSize = AllMethods.GetLittleEndianInt(uncompressedSize, 0); // Gets little endian value of uncompressed size into an integer
// SharpZipLib GZip method called
using (GZipInputStream decompressStream = new GZipInputStream(msi, uncompressedIntSize))
{
using (MemoryStream outputStream = new MemoryStream(uncompressedIntSize))
{
byte[] buffer = new byte[uncompressedIntSize];
decompressStream.Read(buffer, 0, uncompressedIntSize); // Stream is decompressed and read
outputStream.Write(buffer, 0, uncompressedIntSize);
using (var fs = new FileStream(kernelSectionUncompressed, FileMode.Create, FileAccess.Write))
{
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
outputStream.Close();
}
decompressStream.Close();
因此,在此代码段中:
1)压缩段已传入,准备解压缩。
2)未压缩输出的预期大小(存储在文件头中,文件为2字节的Little-Endian值)通过一种方法传递,以将其转换为整数。标头较早删除,因为它不属于压缩的GZIP文件。
3)SharpLibZip的GZIP流是用压缩文件流(msi)和等于int uncompressedIntSize的缓冲区声明的(也已经测试过静态值4096)。
4)我设置了一个MemoryStream来处理将输出写入文件的过程,因为GZipInputStream没有读/写功能;它以预期的解压缩文件大小作为参数(容量)。
5)流的读/写需要byte []数组作为第一个参数,因此我设置了一个byte []数组,该数组具有足够的空间来容纳解压缩输出的所有字节(在这种情况下为3584字节,源自uncompressedIntSize)。
6)int GzipInputStream decompressStream使用.Read以缓冲区作为第一个参数,从偏移量0开始,使用uncompressedIntSize作为计数。检查此处的参数,缓冲区数组的容量仍为3584字节,但仅获得256字节的数据。其余的都是零。
.Read的输出似乎被限制为256个字节,但是我不确定在哪里。流是否有我想念的东西,还是.Read的限制?
答案 0 :(得分:2)
从流中读取时,您需要循环; lazy 的方式可能是:
const_pointer_cast
(但这不能保证在const something
个字节后停止-它将尝试读取到decompressStream.CopyTo(outputStream);
的末尾)
更手动的版本(遵守所施加的长度限制)将是:
uncompressedIntSize
答案 1 :(得分:0)
这个问题原来是我先前在发布的代码中所做的疏忽:
我正在使用的文件有27个节,这些节是GZipped的,但是每个节都有一个标头,如果GZipInput流中的任何一个被击中,它们都会破坏Gzip解压缩。打开基础文件时,它每次都是从头开始(调整为6以避开第一个标头),而不是转到下一个后标头偏移:
brg.BaseStream.Seek(6,SeekOrigin.Begin);
代替:
brg.BaseStream.Seek(absoluteSectionOffset,SeekOrigin.Begin);
这意味着提取的压缩数据是第一个无标题的节+第二节的一部分及其标题的混合物。由于第一部分的长度为256个字节,没有标题,因此该部分已由GZipInput流正确解压缩。但是之后有6个字节的标头将其破坏,导致其余输出为00s。
发生这种情况时,GZipInput流没有引发任何显式错误,因此我错误地认为原因是.Read或流中保留前一遍数据的某些内容。抱歉麻烦了。