简体   繁体   中英

How to recreate a Zip File from a MemoryStream

I've looked around for a solution to my issue but no-one seems to being aiming for quite what I'm trying to achieve.

My problem is such, I have Zip files stored in Azure Blob storage, now for security's sake we have an API2 controller action that provisions these zip files, rather than allowing direct downloading. This action will retrieve the blob, and download it to a stream, so that it can be packaged within a HTTPResponseMessage .

All of the above works, however, when I attempt to recreate the zip file, I'm informed it's corrupted. For now I'm just attempting to have the server (running on localhost) create the zip file, whereas the endgame is to have remote Client applications do this (I'm fairly certain the solution to my issue on the server would be the same.

public class FileActionResult : IHttpActionResult 
{
  private HttpRequestMessage _request;
  private ICloudBlob _blob;

  public FileActionResult(HttpRequestMessage request, ICloudBlob blob)
  {
    _request = request;
    _blob = blob;
  }

  public async Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
  {
    var fileStream = new MemoryStream();
    await _blob.DownloadToStreamAsync(fileStream);

    var byteTest = new byte[fileStream.Length];
    var test = fileStream.Read(byteTest, 0, (int)fileStream.Length);

    try
    {
      File.WriteAllBytes(@"C:\testPlatFiles\test.zip", byteTest);
    }
    catch(ArgumentException ex)
    {
      var a = ex;
    }

    var response = _request.CreateResponse(HttpStatusCode.Accepted);
    response.Content = new StreamContent(fileStream);
    response.Content.Headers.ContentLength = _blob.Properties.Length;
    response.Content.Headers.ContentType = new MediaTypeHeaderValue(_blob.Properties.ContentType);
    //set the fileName
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
      FileName = _blob.Name,
      Size = _blob.Properties.Length
    };
    return response;  
  }
}

I've looked into Zip libraries to see if any present the solution for converting the stream of a zip back to a zip file, but all I can find is reading zip files into streams, or the creation in order to provision a file download instead of a filecreate.

Any help would be much appreciated, thank you.

You use DotNetZip . Its ZipFile class has a static factory method that should do what you want: ZipFile.Read( Stream zipStream ) reads the given stream as a zip file and gives you back a ZipFile instance (which you can use for whatever.

However, if your Stream contains the raw zip data and all you want to do is persist it to disk, you should just be able to write the bytes straight to disk.

If you're getting 'zip file corrupted' errors, I'd look at the content encoding used to send the data to Azure and the content encoding it's sent back with. You should be sending it up to Azure with a content type of application/zip or application/octet-stream and possibly adding metadata to the Azure blob entry to send it down the same way.


Edited To Note: DotNetZip used to live at Codeplex. Codeplex has been shut down. The old archive is still available at Codeplex . It looks like the code has migrated to Github:


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM