首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从byte[]转到MemoryStream,解压缩,然后写到FileStream

如何从byte[]转到MemoryStream,解压缩,然后写到FileStream
EN

Stack Overflow用户
提问于 2019-03-05 06:34:23
回答 3查看 231关注 0票数 0

我不确定我做错了什么。我在获取byte[] (即emailAttachment.Body)并将其传递给ExtractZipFile方法后创建的文件,将其转换为MemoryStream,然后解压缩,将其作为KeyValuePair返回,然后使用FileStream写入文件。

但是,当我打开新创建的文件时,打开它们时出现错误。它们无法打开。

以下内容在同一类中

代码语言:javascript
复制
using Ionic.Zip;

var extractedFiles = ExtractZipFile(emailAttachment.Body);

foreach (KeyValuePair<string, MemoryStream> extractedFile in extractedFiles)
{                               
    string FileName = extractedFile.Key;
    using (FileStream file = new FileStream(CurrentFileSystem + 
    FileName.FileFullPath(),FileMode.Create, System.IO.FileAccess.Write))
    {
        byte[] bytes = new byte[extractedFile.Value.Length];
        extractedFile.Value.Read(bytes, 0, (int) xtractedFile.Value.Length);
        file.Write(bytes,0,bytes.Length);
        extractedFile.Value.Close();
     }
}


private Dictionary<string, MemoryStream> ExtractZipFile(byte[] messagePart)
{
    Dictionary<string, MemoryStream> result = new Dictionary<string,MemoryStream>();
    MemoryStream data = new MemoryStream(messagePart);
    using (ZipFile zip = ZipFile.Read(data))
    {
        foreach (ZipEntry ent in zip)
        {
            MemoryStream memoryStream = new MemoryStream();
            ent.Extract(memoryStream);
            result.Add(ent.FileName,memoryStream);
        }   
    }
    return result;
}

我是不是漏掉了什么?我不想保存原始的压缩文件,只保存从MemoryStream提取的文件。我做错了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-05 06:49:09

在写入MemoryStream之后,您不能将位置设置回0:

代码语言:javascript
复制
MemoryStream memoryStream = new MemoryStream();
ent.Extract(memoryStream);
result.Add(ent.FileName,memoryStream);

正因为如此,当您尝试读取流位置时,流位置将位于末尾,而您将什么也读不到。一定要倒回去:

代码语言:javascript
复制
memoryStream.Position = 0;

此外,您也不必手动处理副本。就让CopyTo方法来处理吧:

代码语言:javascript
复制
extractedFile.Value.CopyTo(file);
票数 1
EN

Stack Overflow用户

发布于 2019-03-05 07:36:03

我建议您在代码中清理对MemoryStream的使用。

我同意调用memoryStream.Position = 0;可以让这段代码正常工作,但在读写内存流时很容易遗漏它。

最好是编写避免bug的代码。

试试这个:

代码语言:javascript
复制
private IEnumerable<(string Path, byte[] Content)> ExtractZipFile(byte[] messagePart)
{
    using (var data = new MemoryStream(messagePart))
    {
        using (var zipFile = ZipFile.Read(data))
        {
            foreach (var zipEntry in zipFile)
            {
                using (var memoryStream = new MemoryStream())
                {
                    zipEntry.Extract(memoryStream);
                    yield return (Path: zipEntry.FileName, Content: memoryStream.ToArray());
                }
            }
        }
    }
}

然后,您的调用代码将如下所示:

代码语言:javascript
复制
foreach (var extractedFile in ExtractZipFile(emailAttachment.Body))
{
    File.WriteAllBytes(Path.Combine(CurrentFileSystem, extractedFile.Path.FileFullPath()), extractedFile.Content);
}

它只需要更少的代码和更好的避免bug的机会。代码中bug的头号预测指标是您编写的代码行数。

票数 1
EN

Stack Overflow用户

发布于 2019-03-05 07:56:00

因为我发现一个简单的操作需要大量的代码,所以这里是我的两点意见。

代码语言:javascript
复制
using Ionic.Zip;

using (var s = new MemoryStream(emailAttachment.Body))
using (ZipFile zip = ZipFile.Read(s))
{
    foreach (ZipEntry ent in zip)
    {
        string path = Path.Combine(CurrentFileSystem, ent.FileName.FileFullPath())
        using (FileStream file = new FileStream(path, FileAccess.Write))
        {
            ent.Extract(file);
        }   
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54992643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档