I pack the file / folder into the archive and give the user the archive when downloading.
The following actions are obtained:

1. Creating an archive and writing it to disk.
2. Download the archive from disk and send it to the user.
3. Delete archive from disk.

So I create an archive

ZipFile.CreateFromDirectory(zipPath, ZipName); 

And so I give out to the client and then it is necessary to delete

 public ActionResult Index() { return File(FilePath, MediaTypeNames.Text.Plain, "File.zip"); } 

Question. Is it possible to write an archive into a variable and then load it from it, and at the end it is simply cleared, bypassing writing to disk *?
* ( assuming that RAM is enough)

  • What is your .NET? If I'm not mistaken, then you can use a MemoryStream for compression. As far as I remember, the class for working with ZIP in .NET 4.5 quite allows itself this, and already give the user the resulting stream MemoryStream. - BlackWitcher 1:58 pm
  • Or, alternatively, read from a stream into an array of bytes ( byte[] ) and return a variable with an array. - BlackWitcher
  • @BlackWitcher Net 4.5. And you have not seen examples? - Rakzin Roman
  • What could - wrote in response. I hope, it is useful and will help. - BlackWitcher

1 answer 1

In .NET 4.5, the System.IO.Compression library has been added to work with data compression (archiving), including working with streams. Try, for example, like this:

 //Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π² памяти FileStream fZip = new MemoryStream(); //Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ ZIP-ΠΏΠΎΡ‚ΠΎΠΊ ZipOutputStream zipOStream = new ZipOutputStream(fZip); //Π‘ΠΊΠ°Π½ΠΈΡ€ΡƒΠ΅ΠΌ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ sourceDirectory Π² поисках Ρ„Π°ΠΉΠ»ΠΎΠ² var allfiles = Directory.EnumerateFiles(sourceDirectory, "*.*", SearchOption.AllDirectories); //ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» foreach (FileInfo fi in allfiles) { //ДобавляСм Π½ΠΎΠ²Ρ‹ΠΉ элСмСнт Π°Ρ€Ρ…ΠΈΠ²Π° ZipEntry entry = new ZipEntry((fi.Name)); zipOStream.PutNextEntry(entry); //ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» ΠΊΠ°ΠΊ ΠΏΠΎΡ‚ΠΎΠΊ ΠΈ Ρ‡ΠΈΡ‚Π°Π΅ΠΌ Π΅Π³ΠΎ Π² ZIP-ΠΏΠΎΡ‚ΠΎΠΊ FileStream fs = File.OpenRead(fi.FullName); try { byte[] transferBuffer[1024]; do { bytesRead = fs.Read(transferBuffer, 0, transferBuffer.Length); zipOStream.Write(transferBuffer, 0, bytesRead); } while (bytesRead > 0); } finally { fs.Close(); } } //Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ наш ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠΈΠΉΡΡ ZIP-ΠΏΠΎΡ‚ΠΎΠΊ, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚Π΄Π°Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ. zipOStream.Finish(); zipOStream.Close(); 

Another option:

 var allfiles = Directory.EnumerateFiles(sourceDirectory, "*.*", SearchOption.AllDirectories); using (var memoryStream = new MemoryStream()) { //Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊ для Π°Ρ€Ρ…ΠΈΠ²Π° Π² памяти. using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) { foreach (var f in allfiles) { var demoFile = archive.CreateEntry(f); } } memoryStream.Seek(0, SeekOrigin.Begin); //Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ (Π±ΡƒΠ΄Π΅Ρ‚ zip-Π°Ρ€Ρ…ΠΈΠ²) ΠΈΠ»ΠΈ ΠΎΡ‚Π΄Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ: //memoryStream.CopyTo(fileStream); } } 

The variant with the archive from the byte array just for ASP .NET MVC is given in English SO . Let me copy the code here:

 using (var compressedFileStream = new MemoryStream()) { //Create an archive and store the stream in memory. using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false)) { foreach (var caseAttachmentModel in caseAttachmentModels) { //Create a zip entry for each attachment var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name); //Get the stream of the attachment using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body)) { using (var zipEntryStream = zipEntry.Open()) { //Copy the attachment stream to the zip entry stream originalFileStream.CopyTo(zipEntryStream); } } } } return new FileContentResult(compressedFileStream.ToArray(), "application/zip") { FileDownloadName = "Filename.zip" }; }