4

So I have achieved zipping the files but now I am having this another issues that the zip folder contains empty file. The size of the file zipped is 0 bytes.

This is how I am zipping my file

try
{
    var outPutDirectory = AppDomain.CurrentDomain.BaseDirectory;
    string logoimage = Path.Combine(outPutDirectory, "images\\error.png");

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.BufferOutput = false;
    HttpContext.Current.Response.ContentType = "application/zip";
    HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=pauls_chapel_audio.zip");

    using (MemoryStream ms = new MemoryStream())
    {
        // create new ZIP archive within prepared MemoryStream
        using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
        {
            var demoFile = zip.CreateEntry(logoimage);
            // add some files to ZIP archive
        }
        ms.WriteTo(HttpContext.Current.Response.OutputStream);
    }

    return true;
}

Another issue is that the zipped folder has the same path as that of the image. So it is like

ZippFolder/A/B/C/image...

I just need

ZipFolder/content
Jehof
  • 34,674
  • 10
  • 123
  • 155
mohsinali1317
  • 4,255
  • 9
  • 46
  • 85
  • 1
    uhm 2 things 1. your code seems to be asp.net and not c# specific? 2. you are making anice memory stream but it is never "prepared" aka set to any content? – Thomas Nov 13 '15 at 08:09
  • I am not sure how to write it. I am new at this thing, can you give an example? – mohsinali1317 Nov 13 '15 at 08:11
  • HttpContext sounds like something from asp.net thus you should add that tag to your question. as for the memoryStream you do new MemoryStream() BUT that only creates an empty memory stream. You set nowhere where the source comes from (as I don't know more details about your project I can't say how you should set / initialize it). You should add where your data SHOULD come from. if it is from a file download / upload dialog,... – Thomas Nov 13 '15 at 08:13
  • It is from a static file for now. – mohsinali1317 Nov 13 '15 at 08:15
  • 1
    but the whole thing should be a web application? – Thomas Nov 13 '15 at 08:16
  • I would recommend this here: http://stackoverflow.com/questions/6213993/how-to-load-a-file-into-memory-stream as what you want is a filestream and not a memorystream then – Thomas Nov 13 '15 at 08:17

1 Answers1

6
var demoFile = zip.CreateEntry(logoimage);

This creates an entry in the ZIP file that has the name logoimage (i.e. /A/B/C/images/error.png or whatever is the full path).

But you never write to that entry, so it’s empty. Also if you want to have a different path, you should specify it there:

var demoFile = zip.CreateEntry("content\\error.png");
using (StreamWriter writer = new StreamWriter(demoFile.Open()))
using (StreamReader reader = new StreamReader(logoimage))
{
    writer.Write(reader.ReadToEnd());
}

Alternatively, you could also skip the StreamWriter completely, and just write to the stream directly:

using (Stream stream = demoFile.Open())
using (StreamReader reader = new StreamReader(logoimage))
{
    reader.BaseStream.CopyTo(stream);
}

Btw. you can skip the outer MemoryStream in which you want to write your zip file first and then write that stream to the OutputStream. Instead, you can just write to that stream directly. Just pass it to the ZipFile constructor:

Stream output = HttpContext.Current.Response.OutputStream;
using (ZipArchive zip = new ZipArchive(output, ZipArchiveMode.Create, true))
{
    …
}
poke
  • 369,085
  • 72
  • 557
  • 602
  • can't he just .CopyTo HttpContext.Current.Response.OutputStream ? instead of writer as that is where he wants to put the data anyway – Thomas Nov 13 '15 at 08:18
  • The problem is not putting output in the output stream. The problem is that he wants to return a zipped file from the HTTP request but he never adds actual content into the zip. – poke Nov 13 '15 at 08:20
  • I am getting this error when I try CopyTo() 'System.IO.StreamReader' does not contain a definition for 'CopyTo' and no extension method 'CopyTo' accepting a first argument of type 'System.IO.StreamReader' could be found (are you missing a using directive or an assembly reference?)' – mohsinali1317 Nov 13 '15 at 08:21
  • @poke yepp I know that he never read anything. What I meant with my post is that in the end he wants to create the zip yes, but also he wants to put it as the http output (as the whole thing shall be a download). does he then need to read the demoFile again in a streamreader and write it to the output or is there a faster way there? – Thomas Nov 13 '15 at 08:22
  • @ChaudhryMohsinAli Yeah, sorry, mixed that up. `CopyTo` only works fro streams, not for StreamReaders/Writers – poke Nov 13 '15 at 08:23
  • Now the image size is 26 KB but it is corrupted or something. The original image is around 15 KB though. – mohsinali1317 Nov 13 '15 at 08:28
  • @Thomas Yes, you could skip the MemoryStream completely, and just write the ZipFile to the OutputStream directly. But you need to read the file in a normal way and pass it to the ZipFile. – poke Nov 13 '15 at 08:29
  • @ChaudhryMohsinAli Try it with a text file, as that will make it easier for you to spot corruptions. Also check, if the zip file content is actually a zip (can you open it with a zip program?), or if it is maybe just some html error from ASP that has a zip extension. Finally, try this offline first, without ASP in between and see if that works for you. – poke Nov 13 '15 at 08:42
  • I fixed it, it was an image file I was trying to read and using stream reader for text files. – mohsinali1317 Nov 13 '15 at 08:51
  • Finally this solution gave me the answer after searching online for 2 days. I am developing a UWP app for Win 8. So, it doesn't have features like Win 10. Have gone through each step of this. Thanks – Keshan Fernando Nov 15 '16 at 01:03