使用C#中的System.IO.Compression压缩内存中的对象

时间:2017-01-28 13:11:48

标签: c# serialization stream zip compression

我正在尝试将类的实例(我们称之为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资源管理器打开它时,出现错误: enter image description here 我在这做错了什么?

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

1 个答案:

答案 0 :(得分:1)

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

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");
    }