【问题标题】:Compressing an object in memory with System.IO.Compression in C#在 C# 中使用 System.IO.Compression 压缩内存中的对象
【发布时间】:2017-01-28 13:11:47
【问题描述】:

我正在尝试将一个类的实例(我们称之为 Car)序列化为一个 xml,然后在内存中将其压缩为一个包含单个文件条目的 zip 文件。 我正在使用 System.IO.Compression.ZipArchive 类来做到这一点:

private byte[] CompressCar(Car car)
{
    using (var carStream = new MemoryStream())
    using (var zipStream = new MemoryStream())
    using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create))
    {
        new XmlSerializer(typeof(Car)).Serialize(carStream, car);
        ZipArchiveEntry entry = archive.CreateEntry("car.xml", CompressionLevel.Optimal);
        using (var zippedFileStream = entry.Open())
        {
            carStream.Seek(0, SeekOrigin.Begin);
            carStream.CopyTo(zippedFileStream);
        }
        return zipStream.ToArray();
    }
}

当我将压缩字节保存到文件中,然后尝试使用 Windows 资源管理器打开它时,出现错误: 我在这里做错了什么?

我查找了其他 StackOverflow 条目,但找不到任何可以解决我的问题的内容。我想在内存中压缩它而不是使用临时文件。

【问题讨论】:

  • 1) 您正在将一个名为 flight 的东西序列化到您的 carStream。你不应该序列化car吗? 2)尝试在返回zipStream.ToArray()之前处理archive(即将返回语句移到最里面的using之外)。
  • 顺便说一句,为什么不直接序列化到zippedFileStream 使用new XmlSerializer(typeof(Car)).Serialize(zippedFileStream, car); 完全消除中间carStream
  • 你说得对。我在调用 ToArray() 之前处理了 ZipArchive 对象,现在它工作正常。感谢您的帮助。
  • 好的,那我来补充一下。

标签: c# serialization stream zip compression


【解决方案1】:

您需要在返回底层zipStream.ToArray() 之前处置ZipArchive。例如,您可以提取以下辅助方法:

public static class SerializationExtensions
{
    public static byte[] ToCompressedXmlZipArchive<T>(T root, string entryName)
    {
        using (var zipStream = new MemoryStream())
        {
            using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create))
            {
                var entry = archive.CreateEntry(entryName, CompressionLevel.Optimal);
                using (var zippedFileStream = entry.Open())
                {
                    new XmlSerializer(typeof(T)).Serialize(zippedFileStream, root); // Possibly use root.GetType() instead of typeof(T)
                }
            }
            return zipStream.ToArray();
        }
    }
}

然后你的方法就变成了:

    private byte[] CompressCar(Car car)
    {
        return SerializationExtensions.ToCompressedXmlZipArchive(car, "car.xml");
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 2020-03-03
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多