C # package files to Zip

In view of the fact that many blogs about C# packaging Zip are relatively wordy and have no comments, which is not suitable for Xiaobai to watch, this close-up is about it

Paste the code first and create one directly Net Core console can run

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;

namespace Zip
{
    class Program
    {
        static void Main(string[] args)
        {
            var zipFiles = new List<ZipFile>
            {
                new ZipFile
                {
                    RelativePath = "1/2/3/Official document endorsement form 223.pdf",
                    Content = Extend.GetBytesFromPath("E:/Official document endorsement form.pdf")
                },
                new ZipFile
                {
                    RelativePath = "1/2/3/Official document endorsement form 2233.pdf", //When the file name under the same path is duplicate, you will be prompted whether to overwrite it during decompression
                    Content = Extend.GetBytesFromPath("E:/Official document endorsement form.pdf")
                }
            };

            var zipBytes = zipFiles.PackedZip();
            zipBytes.WriteToFile("E:/222/Zip test.zip");
            Console.WriteLine("pack Zip success");
            Console.ReadKey();
        }
    }

    public static class Extend
    {
        /// <summary>
        /// Convert to byte array
        /// </summary>
        /// <param name="stream">File stream</param>
        /// <returns></returns>
        public static byte[] ToBytes(this Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // Set the position of the current flow as the beginning of the flow
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

        /// <summary>
        /// Get the contents of the file (byte array)
        /// </summary>
        /// <param name="absolutePath">Absolute path</param>
        /// <returns></returns>
        public static byte[] GetBytesFromPath(string absolutePath)
        {
            using (Stream fileStream = new FileStream(absolutePath, FileMode.OpenOrCreate))
            {
                return fileStream.ToBytes();
            }
        }

        /// <summary>
        /// Byte array write file
        /// </summary>
        /// <param name="bytes">Document content</param>
        /// <param name="absolutePath">Absolute path</param>
        public static void WriteToFile(this byte[] bytes, string absolutePath)
        {
            if (File.Exists(absolutePath))
            {
                File.Delete(absolutePath);
            }

            using (var fs = new FileStream(absolutePath, FileMode.Create))
            {
                fs.Write(bytes, 0, bytes.Length);
            }
        }

        /// <summary>
        /// take Zip Package file description objects into Zip File and returns an array of bytes
        /// </summary>
        /// <param name="zipFiles">Zip File description object array</param>
        /// <returns></returns>
        public static byte[] PackedZip(this List<ZipFile> zipFiles)
        {
            using (Stream memoryStream = new MemoryStream())
            {
                using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                {
                    foreach (var zipFile in zipFiles)
                    {
                        zipArchive.AddFile(zipFile.RelativePath, zipFile.Content);
                    }
                }

                memoryStream.Seek(0, SeekOrigin.Begin); //This sentence should be in using ZipArchive Outside, otherwise the compressed file will be damaged
                return memoryStream.ToBytes();
            }
        }

        /// <summary>
        /// towards Zip Add file to file
        /// </summary>
        /// <param name="zipArchive"></param>
        /// <param name="relativePath">Relative path</param>
        /// <param name="bytes">Document content</param>
        /// <returns></returns>
        private static bool AddFile(this ZipArchive zipArchive, string relativePath, byte[] bytes)
        {
            try
            {
                ZipArchiveEntry entry = zipArchive.CreateEntry(relativePath);
                using (Stream entryStream = entry.Open())
                {
                    entryStream.Write(bytes, 0, bytes.Length);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
    }

    /// <summary>
    /// Description packaged into Zip Information of a file when
    /// </summary>
    public class ZipFile
    {
        /// <summary>
        /// File relative path with file name and extended name
        /// </summary>
        public string RelativePath { get; set; }
        /// <summary>
        /// Byte array (file content)
        /// </summary>
        public byte[] Content { get; set; }
    }
}

It's packed with Net comes with ziprarchive class, which is in system IO. Compression. DLL of system. Assembly IO. Under the compression namespace, there are usually VS installed. Those who want to use other class libraries to operate Zip can go to Nuget, but this is the most used by the author when writing this article

The basic process is as follows:
1. Read the file with FileStream to obtain the file stream, and transfer the file into a byte array; (when operating the file stream, the commonly used bridging method is to use byte array, which is at least the method encapsulated by our company) [such as GetBytesFromPath method in the above code]

2. Create a MemeryStream object and initialize the zipparchive object with this MemeryStream object (zipparchive is a self-contained class for operating Zip in. Net) [such as the PackedZip method in the above code]

p.s. many blogs are initialized with a physical file, and the result can only be saved back to that physical file. ZipArchive class itself does not have a method to export stream objects; But when using stream initialization, when modifying ZipArchive, it will be synchronized to the stream object. With the stream object, there will be a byte array. I can save it back to the physical file or spread it anywhere on the network

3. Use ZipArchiveEntry object to create ZipArchiveEntry object, open the stream of ZipArchiveEntry object and write files into the stream, which is equivalent to loading files into the Zip file. When creating ZipArchiveEntry object, the relative path is used, and the folder does not need to be actually stored in [AddFile method of the above code]
4. After the Zip object is loaded, the flow of the previously initialized ZipArchive object is returned as a byte array. So far, it is done. It is up to you to export it to a physical file or network


Appendix, Microsoft official tutorial:

https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2012/june/clr-what%E2%80%99s-new-in-the-net-4-5-base-class-library

Tags: C# .NET

Posted by Nothadoth on Sun, 22 May 2022 16:51:23 +0300