保存一个zip文件到内存中,并从流中解压缩文件并获取内容

问题描述:

我目前正在努力将Amazon Prime集成到我们的系统上,并且一直在将标签恢复为ZPL格式。保存一个zip文件到内存中,并从流中解压缩文件并获取内容

基本上,Amazon返回一个base64字符串,我们需要将该字符串转换为字节数组,然后将该数组保存为* .gzip文件。从该gzip文件中,我们可以提取内容并获取zpl标签内容。

我的问题是,我们如何在不将任何临时文件存储到系统的情况下完成以上所有操作。我研究了一些解决方案,但没有人为我工作。

我当前的代码如下:

var str = "base64string";  
var label = Convert.FromBase64String(str); 

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

     var entryStream = demoFile.Open(); 

     using (var bw = new BinaryWriter(entryStream)) 
     { 
      bw.Write(label); 
     } 

     var data = new MemoryStream(); 

     using (var zip = ZipFile.Read(entryStream)) 
     { 
      zip["label"].Extract(data); 
     } 

     data.Seek(0, SeekOrigin.Begin); 

     entryStream.Close(); 
    } 

    using (var fileStream = new FileStream(@"D:\test.zip", FileMode.Create)) 
    { 
     memoryStream.Seek(0, SeekOrigin.Begin); 
     memoryStream.CopyTo(fileStream); 
    } 
} 

如果我将文件保存为test.zip,我可以成功地获取标签了。但是,如果我尝试将它直接解压到另一个流,我得到

从ZipArchiveEntry甲流已被处置

+0

'It got error' - 有什么错误? –

+0

“来自ZipArchiveEntry的流已经处理完毕。” –

+0

尝试使用(var fileStream = ...)使用(var archive = ...)范围 – daniell89

我正在反思它。我终于找到了一个简单的方法来做到这一点。我们只需要将base64字符串转换为字节数组,然后使用GzipStream直接解压缩它。如果有人需要,我会将解决方案留在这里。谢谢!

var label = Convert.FromBase64String(str); 

     using (var compressedStream = new MemoryStream(label)) 
     using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) 
     using (var resultStream = new MemoryStream()) 
     { 
      zipStream.CopyTo(resultStream); 
      return resultStream.ToArray(); 
     } 

我已经做了类似的事情的错误,从压缩网页以PNG标签数据响应。我就是这么想的

using (WebClient webClient = new WebClient()) 
{ 
    // Download. Expect this to be a zip file 
    byte[] data = webClient.DownloadData(urlString); 

    MemoryStream memoryStream = new MemoryStream(data); 

    ZipArchive zipArchive = new ZipArchive(memoryStream); 

    foreach (var zipEntry in zipArchive.Entries) 
    { 
     // Can check file name here and ignore anything in zip we're not expecting 
     if (!zipEntry.Name.EndsWith(".png")) continue; 

     // Open zip entry as stream 
     Stream extractedFile = zipEntry.Open(); 

     // Convert stream to memory stream 
     MemoryStream extractedMemoryStream = new MemoryStream(); 
     extractedFile.CopyTo(extractedMemoryStream); 

     // At this point the extractedMemoryStream is a sequence of bytes containing image data. 
     // In this test project I'm pushing that into a bitmap image, just to see something on screen, but could as easily be written to a file or passed for storage to sql or whatever. 
     BitmapDecoder decoder = PngBitmapDecoder.Create(extractedMemoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 
     BitmapFrame frame = decoder.Frames.First(); 
     frame.Freeze(); 
     this.LabelImage.Source = frame; 
    } 
}