简体   繁体   中英

How to go from byte[], to MemoryStream, Unzip, then write to FileStream

I am unsure what I am doing wrong. The files that I create after grabbing a byte[] (which is emailAttachment.Body) and passing it to the method ExtractZipFile, converting it to MemoryStream and then unzipping it, returning it as a KeyValuePair and then Writing to a file using FileStream .

However when I go to open the new created files there is an error in opening them. They are not able to be opened.

The below are in the same class

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;
}

Is there something I am missing? I do not want to save the original zip file just the extracted Files from MemoryStream . What am I doing wrong?

After writing to your MemoryStream, you're not setting the position back to 0:

MemoryStream memoryStream = new MemoryStream();
ent.Extract(memoryStream);
result.Add(ent.FileName,memoryStream);

Because of this, the stream position will be at the end when you try to read from it, and you'll read nothing. Make sure to rewind it:

memoryStream.Position = 0;

Also, you don't have to handle the copy manually. Just let the CopyTo method take care of it:

extractedFile.Value.CopyTo(file);

I'd suggest that you clean up your use of MemoryStream in your code.

I agree that calling memoryStream.Position = 0; will allow this code to work correctly, but it's an easy thing to miss when reading and writing memory streams.

It's better to write code that avoids the bug.

Try this:

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());
                }
            }
        }
    }
}

Then your calling code would look something like this:

foreach (var extractedFile in ExtractZipFile(emailAttachment.Body))
{
    File.WriteAllBytes(Path.Combine(CurrentFileSystem, extractedFile.Path.FileFullPath()), extractedFile.Content);
}

It's just a lot less code and a much better chance of avoiding bugs. The number one predictor of bugs in code is the number of lines of code you write.

Since I find it all a lot of code for a simple operation, here's my two cents.

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);
        }   
    }
}

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