how to avoid [Content_Types].xml in .net's ZipPackage class

笑着哭i 提交于 2019-12-19 05:08:37

问题


I wish to know if there is any way to avoid to have a [Content_Types].xml file inside the zip file while using .net's ZipPackage class.


回答1:


No.

Zip Packages are not (normal) Zip files. They must follow an imposed structure and contain that Content_Types.xml file in the root. ZipPackage = ZipArchive + Structure.

If you want to create (and especially if you want to read) normal Zip archives you will need an extra library, there is no support in the BCL.

See SharpZipLib (GPL) and DotNetZip




回答2:


If you don't call the .Flush() method, there will be no such file




回答3:


Yes you can create zip packages without the extra XML content file added

Inspired by this link: Using System.IO.Packaging to generate a ZIP file

Using above discovery mentioned by Yiping you can avoid the extra xml file added into the package. Save zip stream from memory stream to a physical zip file before zip archive is closed like this:

public static void AddFilesToZip(string zipFilename, List<String> filesToAdd)
{
    using (var memStream = new MemoryStream())
    {
        using (Package zip = System.IO.Packaging.Package.Open(memStream, FileMode.Create))
        {

            foreach (var fileToAdd in filesToAdd)
            {
                string destFilename = ".\\" + Path.GetFileName(fileToAdd);
                Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));

                //Existing parts not likely in fresh memory stream
                if (zip.PartExists(uri))
                {
                    zip.DeletePart(uri);
                }

                PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal);

                using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
                {

                    using (Stream dest = part.GetStream())
                    {
                        CopyStream(fileStream, dest);
                    }
                }
            }

            //The zip Package will add an XML content type file to memeory stream when it closes
            //so before it closes we save the memorystream to physical zip file.
            using (FileStream zipfilestream = new FileStream(zipFilename, FileMode.Create, FileAccess.Write))
            {
                memStream.Position = 0;
                CopyStream(memStream, zipfilestream);
            }

            // That's it. Zip file saved to file. Things added by package after this point will be to memory stream finally disposed.
        }
    }
}



回答4:


Man, this helped me a lot! You rock! I had to use this because my old framework (3.5). Only to complement, see below the implementation of the CopyStream function:

    private void CopyStream(Stream source, Stream target)
    {
        const int bufSize = 0x1000;
        byte[] buf = new byte[bufSize];
        int bytesRead = 0;
        while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
            target.Write(buf, 0, bytesRead);
    }



回答5:


You can also set private field _contentTypeHelper of System.IO.Packaging.Package to null ( using DynamicObject ).




回答6:


Run this function when you finish packing your zip file:

public static void Remove_Content_Types_FromZip(string zipFileName)
    {
        string contents;
        using (ZipFile zipFile = new ZipFile(File.Open(zipFileName, FileMode.Open)))
        {
            /*
            ZipEntry startPartEntry = zipFile.GetEntry("[Content_Types].xml");
            using (StreamReader reader = new StreamReader(zipFile.GetInputStream(startPartEntry)))
            {
                contents = reader.ReadToEnd();
            }
            XElement contentTypes = XElement.Parse(contents);
            XNamespace xs = contentTypes.GetDefaultNamespace();
            XElement newDefExt = new XElement(xs + "Default", new XAttribute("Extension", "sab"), new XAttribute("ContentType", @"application/binary; modeler=Acis; version=18.0.2application/binary; modeler=Acis; version=18.0.2"));
            contentTypes.Add(newDefExt);
            contentTypes.Save("[Content_Types].xml");
            zipFile.BeginUpdate();
            zipFile.Add("[Content_Types].xml");
            zipFile.CommitUpdate();
            File.Delete("[Content_Types].xml");
            */
            zipFile.BeginUpdate();
            try
            {
                zipFile.Delete("[Content_Types].xml");
                zipFile.CommitUpdate();
            }
            catch{}
        }
    }


来源:https://stackoverflow.com/questions/3748970/how-to-avoid-content-types-xml-in-nets-zippackage-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!