Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从另一个zip文件重新创建zip文件_C#_Asp.net_Ziparchive - Fatal编程技术网

C# 从另一个zip文件重新创建zip文件

C# 从另一个zip文件重新创建zip文件,c#,asp.net,ziparchive,C#,Asp.net,Ziparchive,给定一个zip文件,我需要使用指定的压缩级别(例如,无压缩)重新创建它 我就快到了,但得到了一个错误: 失败:中心目录末尾预期的条目数与中心目录中的条目数不对应 如果我将重新创建的zip文件保存到windows,它看起来是正确的(文件大小正确,条目都具有正确的文件大小),但没有一个文件是可提取的 public static byte[] ReCompress(byte[] originalArchive, CompressionLevel newCompressionLevel) { v

给定一个zip文件,我需要使用指定的压缩级别(例如,无压缩)重新创建它

我就快到了,但得到了一个错误:

失败:中心目录末尾预期的条目数与中心目录中的条目数不对应

如果我将重新创建的zip文件保存到windows,它看起来是正确的(文件大小正确,条目都具有正确的文件大小),但没有一个文件是可提取的

public static byte[] ReCompress(byte[] originalArchive, CompressionLevel newCompressionLevel)
{
    var entries = new Dictionary<string, byte[]>();

    ///////////////////////////
    // STEP 1: EXTRACT ALL FILES
    ///////////////////////////
    using (var ms = new MemoryStream(originalArchive))
    using (var originalZip = new ZipArchive(ms, ZipArchiveMode.Read))
    {
        foreach (var entry in originalZip.Entries)
        {
            var isFolder = entry.FullName.EndsWith("/");
            if (!isFolder)
            {
                using (var stream = entry.Open())
                using (var entryMS = new MemoryStream())
                {
                    stream.CopyTo(entryMS);
                    entries.Add(entry.FullName, entryMS.ToArray());
                }

            }
            else
            {
                entries.Add(entry.FullName, new byte[0]);
            }
        }
    }

    ///////////////////////////
    // STEP 2: BUILD ZIP FILE
    ///////////////////////////
    using (var ms = new MemoryStream())
    using (var newArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var uncompressedEntry in entries)
        {
            var newEntry = newArchive.CreateEntry(uncompressedEntry.Key, newCompressionLevel);
            using (var entryStream = newEntry.Open())
            using (var writer = new BinaryWriter(entryStream, Encoding.UTF8))
            {
                writer.Write(uncompressedEntry.Value);
            }
        }
        return ms.ToArray();
    }
}
它创建了一个大小正确的存档结构
90mb
,但没有可提取的文件

public static byte[] ReCompress(byte[] originalArchive, CompressionLevel newCompressionLevel)
{
    var entries = new Dictionary<string, byte[]>();

    ///////////////////////////
    // STEP 1: EXTRACT ALL FILES
    ///////////////////////////
    using (var ms = new MemoryStream(originalArchive))
    using (var originalZip = new ZipArchive(ms, ZipArchiveMode.Read))
    {
        foreach (var entry in originalZip.Entries)
        {
            var isFolder = entry.FullName.EndsWith("/");
            if (!isFolder)
            {
                using (var stream = entry.Open())
                using (var entryMS = new MemoryStream())
                {
                    stream.CopyTo(entryMS);
                    entries.Add(entry.FullName, entryMS.ToArray());
                }

            }
            else
            {
                entries.Add(entry.FullName, new byte[0]);
            }
        }
    }

    ///////////////////////////
    // STEP 2: BUILD ZIP FILE
    ///////////////////////////
    using (var ms = new MemoryStream())
    using (var newArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var uncompressedEntry in entries)
        {
            var newEntry = newArchive.CreateEntry(uncompressedEntry.Key, newCompressionLevel);
            using (var entryStream = newEntry.Open())
            using (var writer = new BinaryWriter(entryStream, Encoding.UTF8))
            {
                writer.Write(uncompressedEntry.Value);
            }
        }
        return ms.ToArray();
    }
}

如果我以
return ms.ToArray()
结束,它将返回一个
~130kb
字节数组。

Zip存档被破坏,因为您在它完成之前从
内存流
读取了它的内容。为了完成存档创建,您需要在调用
ms.ToArray()
之前调用。 在这种情况下,您可以这样做:

using (var ms = new MemoryStream())
{
    using (var newArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var uncompressedEntry in entries)
        {
            var newEntry = newArchive.CreateEntry(uncompressedEntry.Key, newCompressionLevel);
            using (var entryStream = newEntry.Open())
            using (var writer = new BinaryWriter(entryStream, Encoding.UTF8))
            {
                writer.Write(uncompressedEntry.Value);
            }
        }
    }

    return ms.ToArray();
}

很长的一段路是将第一个归档文件提取到一个临时位置,然后将其重新压缩到新的归档文件中。