当前位置: 首页 > 知识库问答 >
问题:

C#内存流

诸葛令
2023-03-14

我在使用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字节小endian值的形式存储在文件头中)通过一个方法传递,以将其转换为整数。由于头文件不是压缩的GZIP文件的一部分,因此会在前面删除。

3)SharpLibZip的GZIP流是使用压缩文件流(msi)和等于int un压缩的IntSize的缓冲区声明的(也使用静态值4096进行了测试)。

4)我设置了一个MemoryStream来处理将输出写入文件,因为GZipInputStream没有读/写;它将预期的解压文件大小作为参数(容量)。

5)流的读/写需要byte[]数组作为第一个参数,所以我设置了一个有足够空间的byte[]数组来获取解压缩输出的所有字节(在这种情况下为3584字节,派生自未压缩IntSize)。

6)int GzipInputStream解压缩流使用。读取缓冲区作为第一个参数,从偏移量0开始,使用未压缩的IntSize作为计数。检查此处的参数,缓冲区数组的容量仍然为3584字节,但只给了256字节的数据。其余为零。

它看起来像. read的输出被限制为256字节,但我不确定在哪里。Streams是否有我错过的东西,或者这是. read的限制?

共有2个答案

周越泽
2023-03-14

这个问题原来是我之前在发布的代码中所做的疏忽:

我正在处理的文件有27个部分是Gzip的,但每个部分都有一个头,如果Gzip输入流命中其中任何一个部分,就会中断Gzip解压缩。打开基本文件时,每次都从开头开始(调整6以避免第一个标题),而不是转到下一个柱头偏移:

BRG。BaseStream。寻找(6,SeekOrigin。开始);

而不是:

轴承。基本流。Seek(绝对分段偏移,请参见起始点开始);

这意味着提取的压缩数据是第二部分的第一个无头部分与其标题的混合体。由于第一部分长度为256字节,没有其标头,因此GZipInput流对该部分进行了正确解压缩。但在这之后是6字节的标头,它会将其打断,导致其余的输出为00s。

发生这种情况时,GZipInput流没有抛出显式错误,因此我错误地假设原因是。读取或流中的某些内容保留了上一次传递的数据。抱歉带来麻烦。

简意
2023-03-14

从流读取时需要循环;懒惰的方法可能是:

decompressStream.CopyTo(outputStream);

(但这并不保证在解压缩字节后停止-它将尝试读取到解压缩流的末尾)

更为手动的版本(遵守规定的长度限制)将是:

const int BUFFER_SIZE = 1024; // whatever
var buffer = ArrayPool<byte>.Shared.Rent(BUFFER_SIZE);
try
{
    int remaining = uncompressedIntSize, bytesRead;
    while (remaining > 0 && // more to do, and making progress
        (bytesRead = decompressStream.Read(
        buffer, 0, Math.Min(remaining, buffer.Length))) > 0)
    {
        outputStream.Write(buffer, 0, bytesRead);
        remaining -= bytesRead;
    }
    if (remaining != 0) throw new EndOfStreamException();
}
finally
{
    ArrayPool<byte>.Shared.Return(buffer);
}
 类似资料:
  • 了解动态内存在 C++ 中是如何工作的是成为一名合格的 C++ 程序员必不可少的。C++ 程序中的内存分为两个部分: 栈:在函数内部声明的所有变量都将占用栈内存。 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。 很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。 在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆

  • 主要内容:1. “手动保留释放”或MRR,2. MRR基本规则,3. “自动参考计数”或ARC内存管理是任何编程语言中最重要的过程之一。它是在需要时分配对象的内存并在不再需要时取消分配的过程。 管理对象内存是一个性能问题; 如果应用程序不释放不需要的对象,则应用程序会因内存占用增加并且性能受损。 Objective-C内存管理技术大致可分为两类 - “手动保留或释放”或MRR “自动参考计数”或ARC 1. “手动保留释放”或MRR 在MRR中,通过跟踪自己的对象来明确管理内存。这是使用一

  • 1. 引言 其实我们不知道的是,早期的计算机是没有内存的,但是如今我们去买电脑时,都会十分关心电脑内存的各种参数,因此可以看出内存对于电脑性能的重要性。那么为什么需要内存呢?换句话说,内存与计算机以及程序之间的关系又是什么呢?本章将会以内存为中心,探讨许多与内存相关的概念和话题,这些概念是学好后续C语言知识不可缺少的基础,因此希望读者认真对待本章节的内容。 2. 计算机程序运行的目的 2.1 什么

  • 我们的软件正在通过一个从内存流读取数据的GZipStream解压某些字节数据。这些数据以4KB的块解压缩,并写入另一个内存流。 我们已经意识到进程分配的内存远高于实际解压的数据。 示例:具有2425536字节的压缩字节数组被解压缩为23050718字节。我们使用的内存分析器显示了方法MemoryStream。设置容量(Int32值)分配的67104936字节。这是保留内存和实际写入内存之间的2.9

  • 本文向大家介绍object-c 的内存管理 ?相关面试题,主要包含被问及object-c 的内存管理 ?时的应答技巧和注意事项,需要的朋友参考一下 如果您通过分配和初始化(比如[[MyClass alloc] init])的方式来创建对象,您就拥 有这个对象,需要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也同样适用。 如果您拷贝一个对象,您也拥有拷贝得到的对象,需要负责该

  • 本文向大家介绍说说C++内存布局?相关面试题,主要包含被问及说说C++内存布局?时的应答技巧和注意事项,需要的朋友参考一下 C/C++程序编译时内存分为5大存储区 (1)栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量值等,其操作方法类似数据结构中的栈。 (2)堆区(heap):一般由程序员分配释放,与数据结构中的堆毫无关系,分配方式类似于链表。 (3)全局/静态区(stati