我试图使用MemoryStream创建一个简单的演示文本文件的ZIP存档,如下所示:

using (var memoryStream = new MemoryStream())
using (var archive = new ZipArchive(memoryStream , ZipArchiveMode.Create))
{
    var demoFile = archive.CreateEntry("foo.txt");

    using (var entryStream = demoFile.Open())
    using (var streamWriter = new StreamWriter(entryStream))
    {
        streamWriter.Write("Bar!");
    }

    using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
    {
        stream.CopyTo(fileStream);
    }
}

如果我运行这段代码,就会创建归档文件本身,但foo.txt不会。

然而,如果我直接用文件流替换MemoryStream,存档将被正确创建:

using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
using (var archive = new ZipArchive(fileStream, FileMode.Create))
{
    // ...
}

是否可以使用MemoryStream来创建没有FileStream的ZIP存档?


当前回答

只是另一个版本的压缩不写任何文件。

string fileName = "export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx";
byte[] fileBytes = here is your file in bytes
byte[] compressedBytes;
string fileNameZip = "Export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip";

using (var outStream = new MemoryStream())
{
    using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
    {
        var fileInArchive = archive.CreateEntry(fileName, CompressionLevel.Optimal);
        using (var entryStream = fileInArchive.Open())
        using (var fileToCompressStream = new MemoryStream(fileBytes))
        {
            fileToCompressStream.CopyTo(entryStream);
        }
    }
    compressedBytes = outStream.ToArray();
}

其他回答

在将流复制到zip流之前,将其位置设置为0。

using (var memoryStream = new MemoryStream())
{
 using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
 {
  var demoFile = archive.CreateEntry("foo.txt");

  using (var entryStream = demoFile.Open())
  using (var streamWriter = new StreamWriter(entryStream))
  {
     streamWriter.Write("Bar!");
  }
 }

 using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
   {
     memoryStream.Position=0;
     memoryStream.WriteTo(fileStream);
   }
 }

MVC的工作解决方案

    public ActionResult Index()
    {
        string fileName = "test.pdf";
        string fileName1 = "test.vsix";
        string fileNameZip = "Export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip";

        byte[] fileBytes = System.IO.File.ReadAllBytes(@"C:\test\test.pdf");
        byte[] fileBytes1 = System.IO.File.ReadAllBytes(@"C:\test\test.vsix");
        byte[] compressedBytes;
        using (var outStream = new MemoryStream())
        {
            using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
            {
                var fileInArchive = archive.CreateEntry(fileName, CompressionLevel.Optimal);
                using (var entryStream = fileInArchive.Open())
                using (var fileToCompressStream = new MemoryStream(fileBytes))
                {
                    fileToCompressStream.CopyTo(entryStream);
                }

                var fileInArchive1 = archive.CreateEntry(fileName1, CompressionLevel.Optimal);
                using (var entryStream = fileInArchive1.Open())
                using (var fileToCompressStream = new MemoryStream(fileBytes1))
                {
                    fileToCompressStream.CopyTo(entryStream);
                }


            }
            compressedBytes = outStream.ToArray();
        }
        return File(compressedBytes, "application/zip", fileNameZip);
    }
using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication
{
    class Program`enter code here`
    {
        static void Main(string[] args)
        {
            using (FileStream zipToOpen = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.Open))
            {
                using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
                {
                    ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
                    using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
                    {
                            writer.WriteLine("Information about this package.");
                            writer.WriteLine("========================");
                    }
                }
            }
        }
    }
}
       private void button6_Click(object sender, EventArgs e)
    {

        //create With Input FileNames
        AddFileToArchive_InputByte(new ZipItem[]{ new ZipItem( @"E:\b\1.jpg",@"images\1.jpg"),
            new ZipItem(@"E:\b\2.txt",@"text\2.txt")}, @"C:\test.zip");

        //create with input stream
        AddFileToArchive_InputByte(new ZipItem[]{ new ZipItem(File.ReadAllBytes( @"E:\b\1.jpg"),@"images\1.jpg"),
            new ZipItem(File.ReadAllBytes(@"E:\b\2.txt"),@"text\2.txt")}, @"C:\test.zip");

        //Create Archive And Return StreamZipFile
        MemoryStream GetStreamZipFile = AddFileToArchive(new ZipItem[]{ new ZipItem( @"E:\b\1.jpg",@"images\1.jpg"),
            new ZipItem(@"E:\b\2.txt",@"text\2.txt")});


        //Extract in memory
        ZipItem[] ListitemsWithBytes = ExtractItems(@"C:\test.zip");

        //Choese Files For Extract To memory
        List<string> ListFileNameForExtract = new List<string>(new string[] { @"images\1.jpg", @"text\2.txt" });
        ListitemsWithBytes = ExtractItems(@"C:\test.zip", ListFileNameForExtract);


        // Choese Files For Extract To Directory
        ExtractItems(@"C:\test.zip", ListFileNameForExtract, "c:\\extractFiles");

    }

    public struct ZipItem
    {
        string _FileNameSource;
        string _PathinArchive;
        byte[] _Bytes;
        public ZipItem(string __FileNameSource, string __PathinArchive)
        {
            _Bytes=null ;
            _FileNameSource = __FileNameSource;
            _PathinArchive = __PathinArchive;
        }
        public ZipItem(byte[] __Bytes, string __PathinArchive)
        {
            _Bytes = __Bytes;
            _FileNameSource = "";
            _PathinArchive = __PathinArchive;

        }
        public string FileNameSource
        {
            set
            {
                FileNameSource = value;
            }
            get
            {
                return _FileNameSource;
            }
        }
        public string PathinArchive
        {
            set
            {
                _PathinArchive = value;
            }
            get
            {
                return _PathinArchive;
            }
        }
        public byte[] Bytes
        {
            set
            {
                _Bytes = value;
            }
            get
            {
                return _Bytes;
            }
        }
    }


     public void AddFileToArchive(ZipItem[] ZipItems, string SeveToFile)
    {

        MemoryStream memoryStream = new MemoryStream();

        //Create Empty Archive
        ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

        foreach (ZipItem item in ZipItems)
        {

            //Create Path File in Archive
            ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);


            //Open File in Archive For Write
            var OpenFileInArchive = FileInArchive.Open();

            //Read Stream
            FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);

            byte[] ReadAllbytes = new byte[4096];//Capcity buffer
            int ReadByte = 0;
            while (fsReader.Position != fsReader.Length)
            {
                //Read Bytes
                ReadByte = fsReader.Read(ReadAllbytes, 0, ReadAllbytes.Length);

                //Write Bytes
                OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
            }
            fsReader.Dispose();
            OpenFileInArchive.Close();


        }
        archive.Dispose();

        using (var fileStream = new FileStream(SeveToFile, FileMode.Create))
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.CopyTo(fileStream);
        }





    }
     public MemoryStream  AddFileToArchive(ZipItem[] ZipItems)
    {

        MemoryStream memoryStream = new MemoryStream();

        //Create Empty Archive
        ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

        foreach (ZipItem item in ZipItems)
        {

            //Create Path File in Archive
            ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);


            //Open File in Archive For Write
            var OpenFileInArchive = FileInArchive.Open();

            //Read Stream
            FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);

            byte[] ReadAllbytes = new byte[4096];//Capcity buffer
            int ReadByte = 0;
            while (fsReader.Position != fsReader.Length)
            {
                //Read Bytes
                ReadByte = fsReader.Read(ReadAllbytes, 0, ReadAllbytes.Length);

                //Write Bytes
                OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
            }
            fsReader.Dispose();
            OpenFileInArchive.Close();


        }
        archive.Dispose();




        return memoryStream;


    }

     public void AddFileToArchive_InputByte(ZipItem[] ZipItems, string SeveToFile)
    {

        MemoryStream memoryStream = new MemoryStream();

        //Create Empty Archive
        ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

        foreach (ZipItem item in ZipItems)
        {

            //Create Path File in Archive
            ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);


            //Open File in Archive For Write
            var OpenFileInArchive = FileInArchive.Open();

            //Read Stream
          //  FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);

            byte[] ReadAllbytes = new byte[4096];//Capcity buffer
            int ReadByte = 4096 ;int  TotalWrite=0;
            while (TotalWrite != item.Bytes.Length)
            {

                if(TotalWrite+4096>item.Bytes.Length)
                 ReadByte=item.Bytes.Length-TotalWrite;



                Array.Copy(item.Bytes, TotalWrite, ReadAllbytes, 0, ReadByte);




                //Write Bytes
                OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
                TotalWrite += ReadByte;
            }

            OpenFileInArchive.Close();


        }
        archive.Dispose();

        using (var fileStream = new FileStream(SeveToFile, FileMode.Create))
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.CopyTo(fileStream);
        }


    }
     public MemoryStream  AddFileToArchive_InputByte(ZipItem[] ZipItems)
    {

        MemoryStream memoryStream = new MemoryStream();

        //Create Empty Archive
        ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

        foreach (ZipItem item in ZipItems)
        {

            //Create Path File in Archive
            ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);


            //Open File in Archive For Write
            var OpenFileInArchive = FileInArchive.Open();

            //Read Stream
          //  FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);

            byte[] ReadAllbytes = new byte[4096];//Capcity buffer
            int ReadByte = 4096 ;int  TotalWrite=0;
            while (TotalWrite != item.Bytes.Length)
            {

                if(TotalWrite+4096>item.Bytes.Length)
                 ReadByte=item.Bytes.Length-TotalWrite;



                Array.Copy(item.Bytes, TotalWrite, ReadAllbytes, 0, ReadByte);




                //Write Bytes
                OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
                TotalWrite += ReadByte;
            }

            OpenFileInArchive.Close();


        }
        archive.Dispose();



        return memoryStream;
    }

     public void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName)
     {
         //Opens the zip file up to be read
         using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
         {
             if (Directory.Exists(destinationDirectoryName)==false )
                 Directory.CreateDirectory(destinationDirectoryName);

             //Loops through each file in the zip file
             archive.ExtractToDirectory(destinationDirectoryName);

         }
     }  
     public void   ExtractItems(string sourceArchiveFileName,List< string> _PathFilesinArchive, string destinationDirectoryName)
     {

         //Opens the zip file up to be read
         using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
         {


             //Loops through each file in the zip file
             foreach (ZipArchiveEntry file in archive.Entries)
             {
                 int PosResult = _PathFilesinArchive.IndexOf(file.FullName);
                 if (PosResult != -1)
                 {
                     //Create Folder
                     if (Directory.Exists( destinationDirectoryName + "\\" +Path.GetDirectoryName( _PathFilesinArchive[PosResult])) == false)
                         Directory.CreateDirectory(destinationDirectoryName + "\\" + Path.GetDirectoryName(_PathFilesinArchive[PosResult]));

                     Stream OpenFileGetBytes = file.Open();

                     FileStream   FileStreamOutput = new FileStream(destinationDirectoryName + "\\" + _PathFilesinArchive[PosResult], FileMode.Create);

                     byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                     int ReadByte = 0; int TotalRead = 0; 
                     while (TotalRead != file.Length)
                     {
                         //Read Bytes
                         ReadByte = OpenFileGetBytes.Read(ReadAllbytes, 0, ReadAllbytes.Length);
                         TotalRead += ReadByte;

                         //Write Bytes
                         FileStreamOutput.Write(ReadAllbytes, 0, ReadByte);
                     }

                     FileStreamOutput.Close();
                     OpenFileGetBytes.Close();



                     _PathFilesinArchive.RemoveAt(PosResult);
                 }

                 if (_PathFilesinArchive.Count == 0)
                     break;
             }
         }


     }

     public ZipItem[] ExtractItems(string sourceArchiveFileName)
     {
       List<  ZipItem> ZipItemsReading = new List<ZipItem>();
         //Opens the zip file up to be read
         using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
         {


             //Loops through each file in the zip file
             foreach (ZipArchiveEntry file in archive.Entries)
             {
                 Stream OpenFileGetBytes = file.Open();

                 MemoryStream memstreams = new MemoryStream();
                 byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                 int ReadByte = 0; int TotalRead = 0;
                 while (TotalRead != file.Length)
                 {
                     //Read Bytes
                     ReadByte = OpenFileGetBytes.Read(ReadAllbytes, 0, ReadAllbytes.Length);
                     TotalRead += ReadByte;

                     //Write Bytes
                     memstreams.Write(ReadAllbytes, 0, ReadByte);
                 }

                 memstreams.Position = 0;
                 OpenFileGetBytes.Close();
                 memstreams.Dispose();

                 ZipItemsReading.Add(new ZipItem(memstreams.ToArray(),file.FullName));


             }
         }

         return ZipItemsReading.ToArray();
     }
     public ZipItem[] ExtractItems(string sourceArchiveFileName,List< string> _PathFilesinArchive)
     {
       List<  ZipItem> ZipItemsReading = new List<ZipItem>();
         //Opens the zip file up to be read
         using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
         {

             //Loops through each file in the zip file
             foreach (ZipArchiveEntry file in archive.Entries)
             {
                 int PosResult = _PathFilesinArchive.IndexOf(file.FullName); 
                 if (PosResult!= -1)
                 {
                     Stream OpenFileGetBytes = file.Open();

                     MemoryStream memstreams = new MemoryStream();
                     byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                     int ReadByte = 0; int TotalRead = 0;  
                     while (TotalRead != file.Length)
                     {
                         //Read Bytes
                         ReadByte = OpenFileGetBytes.Read(ReadAllbytes, 0, ReadAllbytes.Length);
                         TotalRead += ReadByte;

                         //Write Bytes
                         memstreams.Write(ReadAllbytes, 0, ReadByte);
                     }

                     //Create item
                     ZipItemsReading.Add(new ZipItem(memstreams.ToArray(),file.FullName));

                     OpenFileGetBytes.Close();
                     memstreams.Dispose();



                     _PathFilesinArchive.RemoveAt(PosResult);
                 }

                 if (_PathFilesinArchive.Count == 0)
                     break;


             }
         }

         return ZipItemsReading.ToArray();
     }

您需要完成写入内存流,然后读取缓冲区。

        using (var memoryStream = new MemoryStream())
        {
            using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create))
            {
                var demoFile = archive.CreateEntry("foo.txt");

                using (var entryStream = demoFile.Open())
                using (var streamWriter = new StreamWriter(entryStream))
                {
                    streamWriter.Write("Bar!");
                }
            }

            using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
            {
                var bytes = memoryStream.GetBuffer();
                fileStream.Write(bytes,0,bytes.Length );
            }
        }