我目前正致力于在我们的系统上集成Amazon Prime,并坚持以ZPL格式取回标签。
基本上,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 :(得分:1)
我做过类似的事情,从压缩的网页回复中获取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;
}
}
答案 1 :(得分:0)
我在思考它。我终于找到了一种简单的方法。我们只需要将base64字符串转换为bytes数组,并使用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();
}