C# ZipArchive“找不到中央目录记录的结尾”

Mar*_*rio 5 c# zip ziparchive

我创建了一个 BizTalk 自定义管道组件,它将所有消息部分压缩到一个 zip 流中。在一些失败之后,我在一个单独的测试项目中创建了以下测试方法。

基本上,我得到一个 XML 文件,其中包含一个文件名和一个 UUID,我用它来调用存储过程并获取数据库条目的 Base64 编码内容。base64 内容似乎有效,因为在对其进行解码并将其保存到文件系统后,Windows 资源管理器可以毫无问题地读取文件。

将存档流保存到文件系统后,当我尝试提取文件时,我从 7Zip 收到以下错误消息:“数据意外结束”。如果我尝试仅使用 7Zip 打开文件,则没有问题。我什至可以从 7Zip 资源管理器中打开文件。

如果我尝试使用以下代码从 C# 读取文件,则会收到错误消息:“找不到中央目录记录的结尾。”

解压代码:

    private static void ReadDat() {

        var path = @"...\zip\0e00128b-0a6e-4b99-944d-68e9c20a51c2.zip";

        var stream = System.IO.File.OpenRead(path);
        // End of Central Directory record could not be found:
        var zipArchive = new ZipArchive(stream, ZipArchiveMode.Read, false);
        foreach(var zipEntry in zipArchive.Entries) {

            var stream = zipEntry.Open();
            Console.WriteLine(stream.Length);

        }

    }
Run Code Online (Sandbox Code Playgroud)

邮政编码:

    private static void StreamUuidList() {

        var path = @"...\2017-08-05T132705.xml";
        var xdoc = XDocument.Load(System.IO.File.OpenRead(path));
        var files = xdoc.Root.Descendants().Where(d => d.Name.LocalName.Equals("NodeName"));

        using (var archiveStream = new MemoryStream())
        using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true)) {

            foreach (var file in files) {

                var fileName = file.Elements().Where(e => e.Name.LocalName.Equals("FileName")).FirstOrDefault()?.Value ?? "";
                var streamUuid = file.Elements().Where(e => e.Name.LocalName.Equals("StreamUUID")).FirstOrDefault()?.Value ?? "";                    

                // validation here...

                // get base64 content and convert content
                var base64Content = GetStreamContent(streamUuid);
                var data = Convert.FromBase64String(base64Content);
                var dataStream = new MemoryStream(data);
                dataStream.Seek(0, SeekOrigin.Begin);

                // debug - save to file location
                using (var fileStream = new FileStream($@"...\files\{fileName}", FileMode.Create)) {

                    dataStream.CopyTo(fileStream);

                }
                dataStream.Seek(0, SeekOrigin.Begin);

                // create zip entry
                var zipFile = archive.CreateEntry(fileName, GetCompressionLevelFromString("Optimal"));
                using (var zipFileStream = zipFile.Open()) {

                    // copy data from mesage part stream into zip entry stream
                    dataStream.Seek(0, SeekOrigin.Begin);
                    dataStream.CopyTo(zipFileStream);

                }

                Console.WriteLine(fileName + ": " + streamUuid);

            }

            // debug - save to file location
            archiveStream.Seek(0, SeekOrigin.Begin);
            using (var fileStream = new FileStream($@"...\zip\{Guid.NewGuid()}.dat", FileMode.Create)) {

                archiveStream.CopyTo(fileStream);

            }
            // debug end

        }

    }
Run Code Online (Sandbox Code Playgroud)