GZipStream - 即使使用刷新,写入也不写入所有压缩数据?

2023-11-23

我在针对 .Net 3.5 的 gzipstream 方面遇到了一个棘手的问题。这是我第一次使用 gzipstream,但是我根据许多教程进行了建模,包括here我仍然被困住了。

我的应用程序将数据表序列化为 xml 并插入到数据库中,将压缩数据以及未压缩缓冲区的原始长度存储到 varbinary(max) 字段中。然后,当我需要时,我检索该数据并将其解压缩并重新创建数据表。解压似乎失败了。

EDIT:遗憾的是,按照建议将 GetBuffer 更改为 ToArray 后,我的问题仍然存在。代码更新如下

压缩代码:

DataTable dt = new DataTable("MyUnit");
//do stuff with dt
//okay...  now compress the table
using (MemoryStream xmlstream = new MemoryStream())
{
    //instead of stream, use xmlwriter?
    System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
    settings.Encoding = Encoding.GetEncoding(1252);
    settings.Indent = false;
    System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(xmlstream, settings);
    try
    {
        dt.WriteXml(writer);
        writer.Flush();
    }
    catch (ArgumentException)
    {
        //likely an encoding issue...  okay, base64 encode it
        var base64 = Convert.ToBase64String(xmlstream.ToArray());
        xmlstream.Write(Encoding.GetEncoding(1252).GetBytes(base64), 0, Encoding.GetEncoding(1252).GetBytes(base64).Length);
    }

    using (MemoryStream zipstream = new MemoryStream())
    {
        GZipStream zip = new GZipStream(zipstream, CompressionMode.Compress);
        log.DebugFormat("Compressing commands...");
        zip.Write(xmlstream.GetBuffer(), 0, xmlstream.ToArray().Length);
        zip.Flush();
        float ratio = (float)zipstream.ToArray().Length / (float)xmlstream.ToArray().Length;
        log.InfoFormat("Resulting compressed size is {0:P2} of original", ratio);

        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.CommandText = "INSERT INTO tinydup (lastid, command, compressedlength) VALUES (@lastid,@compressed,@length)";
            cmd.Connection = db;
            cmd.Parameters.Add("@lastid", SqlDbType.Int).Value = lastid;
            cmd.Parameters.Add("@compressed", SqlDbType.VarBinary).Value = zipstream.ToArray();
            cmd.Parameters.Add("@length", SqlDbType.Int).Value = xmlstream.ToArray().Length;
            cmd.ExecuteNonQuery();

        }
    }

解压代码:

/* This is an encapsulation of what I get from the database
 public class DupUnit{
    public uint lastid;
    public uint complength;
    public byte[] compressed;
}*/
  //I have already retrieved my list of work to do from the database in a List<Dupunit> dupunits
foreach (DupUnit unit in dupunits)
{
    DataSet ds = new DataSet();
    //DataTable dt = new DataTable();
    //uncompress and extract to original datatable
    try
    {
        using (MemoryStream zipstream = new MemoryStream(unit.compressed))
        {
            GZipStream zip = new GZipStream(zipstream, CompressionMode.Decompress);
            byte[] xmlbits = new byte[unit.complength];
            //WHY ARE YOU ALWAYS 0!!!!!!!!
            int bytesdecompressed = zip.Read(xmlbits, 0, unit.compressed.Length);
            MemoryStream xmlstream = new MemoryStream(xmlbits);
            log.DebugFormat("Uncompressed XML against {0} is: {1}", m_source.DSN, Encoding.GetEncoding(1252).GetString(xmlstream.ToArray()));
            try{
               ds.ReadXml(xmlstream);
            }catch(Exception)
            {
                //it may have been base64 encoded...  decode first.
               ds.ReadXml(Encoding.GetEncoding(1254).GetString(
                 Convert.FromBase64String(
                 Encoding.GetEncoding(1254).GetString(xmlstream.ToArray())))
                 );
            }
            xmlstream.Dispose();
        }
    }
    catch (Exception e)
    {
        log.Error(e);
        Thread.Sleep(1000);//sleep a sec!
        continue;
    }

请注意上面的评论... bytesdecompressed 始终为 0。有什么想法吗?我做错了吗?

EDIT 2:

所以这很奇怪。我在解压例程中添加了以下调试代码:

   GZipStream zip = new GZipStream(zipstream, CompressionMode.Decompress);
   byte[] xmlbits = new byte[unit.complength];
   int offset = 0;
   while (zip.CanRead && offset < xmlbits.Length)
   {
       while (zip.Read(xmlbits, offset, 1) == 0) ;
       offset++;
   }

调试时,有时该循环会完成,但有时会挂起。当我停止调试时,它将位于 1616 字节中的第 1600 字节。我会继续,但它根本不会移动。

EDIT 3:该错误似乎存在于压缩代码中。无论出于何种原因,它都没有保存所有数据。当我尝试使用第三方 gzip 机制解压缩数据时,我只得到部分原始数据。

我会开始赏金,但到目前为止我真的没有太多声誉可以给予:-(


终于找到了答案。压缩数据不完整,因为 GZipStream.Flush() 绝对没有执行任何操作来确保所有数据都在缓冲区之外 - 您需要使用 GZipStream.Close() 作为这里指出。当然,如果你压缩得不好,一切都会走下坡路——如果你尝试解压缩它,你总是会从 Read() 返回 0。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GZipStream - 即使使用刷新,写入也不写入所有压缩数据? 的相关文章

  • 为什么“dtoa.c”包含这么多代码?

    我将是第一个承认我对低级编程的整体知识有点稀疏的人 我理解许多核心概念 但我不经常使用它们 话虽这么说 我对需要多少代码感到非常惊讶dtoa c http www netlib org fp dtoa c 在过去的几个月里 我一直致力于用
  • 为什么我应该使用内联代码? [复制]

    这个问题在这里已经有答案了 我是一名 C C 开发人员 这里有几个始终困扰我的问题 常规 代码和内联代码之间有很大区别吗 主要区别是什么 内联代码只是宏的一种 形式 吗 选择内联代码时必须进行什么样的权衡 Thanks 表现 正如之前的答案
  • C - 计算文件中的单词、字符和行数。字符数

    我必须用 C 编写一段代码 输出给定文件中的字符数 行数和单词数 任务看起来很简单 但我现在真的不确定出了什么问题 所以 这是代码 include
  • 将 ARGB 拆分为字节值

    我有一个 ARGB 值存储为 int 类型 它是通过调用 ToArgb 来存储的 我现在想要来自 int 值的各个颜色通道的字节值 例如 int mycolor 16744448 byte r g b a GetBytesFromColor
  • 线程独占数据:如何存储和访问?

    NET 中是否有可能将对象实例绑定到线程的当前执行上下文 这样在代码的任何部分我都可以做类似的事情CurrentThread MyObjectData DoOperation 并确保我访问特定于线程的数据 谢谢 你可以看一下线程静态属性 h
  • 更改图像颜色与透明背景

    我需要使用 c System Drawings 将透明背景上带有绿色圆圈的图像加载到位图图像中 这是最简单的部分 但是 我需要在将其添加到更大的图像之前更改圆圈的颜色 而不影响周围的透明度 就我而言 我需要将圆圈颜色更改为黄色并将其添加为太
  • 错误:“运行所选代码生成器时出错:包恢复失败”

    我正在尝试将控制器添加到 ASP NET Core 项目中的解决方案中 当我尝试这样做时 我收到此错误 我收到相同的消息 为控制器添加最小依赖项和完整依赖项 我也有这个问题 使用实体框架添加控制器 gt 带有操作的 API 控制器 将给出
  • 析构函数与成员函数竞赛

    当我在析构函数内时 其他线程是否可能开始执行对象的成员函数 遇到这种情况该如何处理呢 C 没有内在的保护来防止在删除对象后使用它 忘记竞争条件 另一个线程可以在完全删除你的对象后使用你的对象 Either 确保只有一个位置 代码拥有该对象
  • 微软怎么能说WinAPI中一个字的大小是16位呢?

    我刚刚开始学习WinAPI 在MSDN中 对WORD数据类型提供了以下解释 WORD16 位无符号整数 范围是十进制 0 到 65535 该类型在 WinDef h 中声明如下 typedef 无符号短 WORD 很简单 而且它与我一直在使
  • 如何在Unity Inspector中创建多维数组?

    如何在 Unity Inspector 中创建枚举多维数组并使其可序列化 以便我可以从不同的脚本调用它 public enum colors red blue green yellow cyan white purple public in
  • 如何解析多态 JSON 数组?

    我有一个 JSON 格式的文件 其中包含个人用户的记录 一些用户的记录中间有一个评论字段 我只想解析顶级项目 全名 贡献者姓名 电子邮件 使用 Newtonsoft JSON 解析器 但我似乎无法让它识别单个对象 当我将整个字符串解析为一个
  • ef core 在更新数据库期间不使用 ASPNETCORE_ENVIRONMENT

    我使用 Visual Studio 通过一定的迁移来更新我的所有环境 使用下面的命令效果很好 update database Migration initMigrationProduct c ProductContext Environme
  • 为什么最小的 int -2147483648 的类型为“long”? [复制]

    这个问题在这里已经有答案了 对于一个学校项目 我必须编写 C 函数 printf 的代码 一切进展顺利 但有一个问题我找不到好的答案 所以我来了 printf PRINTF d t d n 2147483648 告诉我 gcc Werror
  • 如何将 Boost Spirit 自动规则与 AST 结合使用?

    编辑 当我想在另一个规则上使用它时 我扩展了 sehe 的示例以显示问题 http liveworkspace org code 22lxL7 http liveworkspace org code 22lxL7 17 我正在尝试提高 Bo
  • 使用“const cv::Mat &”、“cv::Mat &”、“cv::Mat”或“const cv::Mat”作为函数参数的区别?

    我已经彻底搜索过 但没有找到一个简单的答案 传递 opencv 矩阵 cv Mat 作为函数的参数 我们传递一个智能指针 我们对函数内部的输入矩阵所做的任何更改也会改变函数范围之外的矩阵 我读到 通过将矩阵作为 const 引用传递 它不会
  • 如何在realm-dotnet中存储System.Collections.Generic.Dictionary

    我正在尝试将 Realm NET 集成到我的 uwp 项目中 我想知道是否有任何方法可以在 Realm dotnet 库中存储 System Collections Generic Dictionary 我试过这个 public class
  • NSubstitute - 测试特定的 linq 表达式

    我在当前正在开发的 MVC 3 应用程序中使用存储库模式 我的存储库界面如下所示 public interface IRepository
  • 如何使用 .NET 捕获我的桌面视频?

    我想知道是否有任何方法可以使用 NET 捕获我的桌面的视频 截屏视频 我并不是在寻找截屏软件 而只是在寻找一种可以让我自己生成桌面视频的技术 我想过拍摄多个屏幕截图 但我不确定如何以编程方式生成带有图像序列的视频 有人有主意吗 Thanks
  • 打印任何类型的数组和列表的通用方法[重复]

    这个问题在这里已经有答案了 每当我调试一段涉及整数 双精度 字符串等数组或列表的代码时 有时我更喜欢打印它们 我为此所做的是为不同类型编写重载的 printArray printList 方法 for e g 我可能有这 3 种方法来打印各
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C

随机推荐

  • Maven:在测试前提取依赖资源

    我有一个多模块 Maven 项目 一个子项目托管 XSL XML 资源文件 另一个项目托管需要在其单元测试中使用这些文件的 Java 代码 在依赖项的 jar 中 资源位于文件夹中xml resources 我找到了这个example并尝试
  • 链接器命令失败,退出代码为 1(使用 -v 查看调用)、Xcode 8、Swift 3

    我无法摆脱这个错误 我尝试过各种方法 例如清除派生数据 首选项 gt 位置 gt 单击灰色箭头在 Finder 中打开派生数据文件夹 gt 右键单击 移至垃圾箱 清理项目 CMD Shift K 或 Product gt Clean 更新
  • 设置 Android 照片 EXIF 方向

    我编写了一个以编程方式捕获照片的 Android 活动 我想将图像保存为具有正确 EXIF 方向数据的 JPEG 就像本机 Android 相机应用程序自动执行的那样 这是实际拍照的方法 我删除了 try catch 块 private v
  • 如何检查列表中的所有元素是否都存在于 pandas 列中

    我有一个数据框和一个列表 df pd DataFrame id 1 2 3 4 5 6 7 8 char a b a b c a c b c c a d c d a names a c 我只想在两者都满足的情况下获取行a and c两者都存
  • 每个 Windows 操作系统的注册表中的 CurrentVersion 值

    我想知道CurrentVersion每个操作系统的值 HKLM SOFTWARE Microsoft Windows NT CurrentVersion 例如 我的机器上安装了 Windows 7 Professional 并且Curren
  • MVC4 中捆绑的正确方法

    我对捆绑脚本和样式文件的正确方法有点困惑 目前 我的 BundleConfig cs 如下所示 bundles Add new ScriptBundle bundles jquery Include Scripts jquery versi
  • 你能摆脱 Groovy 的“each”闭包吗?

    是否有可能break来自 Groovy each Closure 或者我应该使用经典循环 不 你不能在不抛出异常的情况下中止 每个 如果您希望中断在特定条件下中止 您可能需要经典循环 或者 您可以使用 find 闭包而不是each 并在需要
  • 在 Storyboard 中创建自定义 UITableViewCell

    想要创建一个静态菜单 IOS 5 并尝试在故事板中创建自定义单元格 然后加载到分组的表格视图上 我已经创建了出口 property nonatomic strong IBOutlet UITableViewCell labelCell Vi
  • 缺少“PLAIN”nodemailer 的凭据

    我正在尝试在联系表单中使用 nodemailer 来接收反馈并将其直接发送到电子邮件 这是下面的表格
  • 如何获取该文件夹中的文件夹列表?

    如何获取该文件夹中的文件夹列表 查找第一个文件Ex FindExSearchLimitToDirectories WIN32 FIND DATA fi HANDLE h FindFirstFileEx dir FindExInfoStand
  • TypeScript:从node_modules导入外部模块

    有一个npm模块one two three例如 里面有TS文件index ts 主要 和functions ts 函数 ts export interface IPoint x number y number export function
  • Git 命令提交所有更改,包括删除或创建的文件

    对已跟踪的文件进行更改后git我通常会做 git commit a m a message describing what you did 其次是 git push origin master 提交并将所有更改推送到我的 Github 帐户
  • 从 Excel VBA 打开 Access

    编辑 这个问题的答案可以在已接受答案的评论中找到 我正在尝试通过单击 Excel 文件中的按钮来打开 Access 数据库 我目前有这个代码 Private Sub bttnToAccess Click Dim db As Access A
  • 回形针自定义:路径和:url

    我在尝试使用回形针自定义 has attached file 的 path 和 url 选项时遇到一些问题 我有一个名为 Asset 的多态类 其中包含 class Asset lt ActiveRecord Base belongs to
  • 使用 client-go 访问 GKE 集群外部的 Kubernetes GKE 集群?

    我在 GKE 上运行多个 kubernetes 集群 假设 clusterS 和 cluster B 我想从在其中一个集群中运行的应用程序中的 client go 访问这两个集群 例如 从在 clusterA 上运行的应用程序访问 clus
  • 是否可以在 Sitemesh 中多次装饰?

    I m trying to do something like this 对于 admin 的所有请求 我需要使用 B 装饰器来装饰页面 而且 B 装饰器必须包含在 A 装饰器的内容中 A 装饰器是主应用程序布局 我如何使用 Sitemes
  • 更改iOS键盘动画时间

    有没有办法改变iOS键盘动画的时间 我实际上已经找到了更好的解决方案 您可以做的是以编程方式使文本字段或文本视图成为动画中的第一响应者 并具有您选择的持续时间 让键盘在一秒钟内出现的示例可能是 UIView animateWithDurat
  • iOS 8 YouTube 视频嵌入

    我面临着我似乎无法理解的问题 我的这段代码在 Xcode 5 和 iOS 7 中完美运行 void viewDidLoad super viewDidLoad Do any additional setup after loading th
  • Cookie 过期在 C# 中不起作用

    我尝试使用 C 4 0 和以下代码制作持久 cookie HttpCookie AssoCookie new HttpCookie AssociateCode AssociateCode AssoCookie Expires DateTim
  • GZipStream - 即使使用刷新,写入也不写入所有压缩数据?

    我在针对 Net 3 5 的 gzipstream 方面遇到了一个棘手的问题 这是我第一次使用 gzipstream 但是我根据许多教程进行了建模 包括here我仍然被困住了 我的应用程序将数据表序列化为 xml 并插入到数据库中 将压缩数