使用System.IO.Compression在内存中创build一个ZIP存档
我试图创build一个ZIP存档与一个简单的演示文本文件使用MemoryStream
如下:
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); } }
如果我运行这个代码,档案文件本身被创build,但foo.txt不是。
但是,如果我直接用文件streamreplaceMemoryStream
,则会正确创build存档:
using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create)) using (var archive = new ZipArchive(fileStream, FileMode.Create)) { // ... }
是否有可能使用MemoryStream
创build没有FileStream
的ZIP压缩文件?
感谢https://stackoverflow.com/a/12350106/222748我得到了:;
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.Seek(0, SeekOrigin.Begin); memoryStream.CopyTo(fileStream); } }
因此,我们需要在ZipArchive上调用dispose,然后才能使用它,这意味着将“true”作为第三个parameter passing给ZipArchive,因此我们仍然可以在处理它之后访问stream。
只是另一个版本的压缩没有写任何文件。
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(); }
将stream的位置设置为0,然后将其复制到zipstream中。
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); } }
您需要完成写入内存stream,然后读取缓冲区。
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 ); } }
这是将实体转换为XML文件然后进行压缩的方法:
private void downloadFile(EntityXML xml) { string nameDownloadXml = "File_1.xml"; string nameDownloadZip = "File_1.zip"; var serializer = new XmlSerializer(typeof(EntityXML)); Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("content-disposition", "attachment;filename=" + nameDownloadZip); using (var memoryStream = new MemoryStream()) { using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) { var demoFile = archive.CreateEntry(nameDownloadXml); using (var entryStream = demoFile.Open()) using (StreamWriter writer = new StreamWriter(entryStream, System.Text.Encoding.UTF8)) { serializer.Serialize(writer, xml); } } using (var fileStream = Response.OutputStream) { memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.CopyTo(fileStream); } } Response.End();
}
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(); }