C # распаковывать данные из потока памяти [дубликат]

def flatten(l, a):
    for i in l:
        if isinstance(i, list):
            flatten(i, a)
        else:
            a.append(i)
    return a

print(flatten([[[1, [1,1, [3, [4,5,]]]], 2, 3], [4, 5],6], []))

# [1, 1, 1, 3, 4, 5, 2, 3, 4, 5, 6]
28
задан user1621791 3 October 2012 в 21:00
поделиться

4 ответа

Мы используем DotNetZip , и я могу разархивировать содержимое zip-файла из Stream в память. Вот пример кода для извлечения специально названного файла из потока (LocalCatalogZip) и возврата потока для чтения этого файла, но его было бы легко развернуть.

    private static MemoryStream UnZipCatalog()
    {
        MemoryStream data = new MemoryStream();
        using (ZipFile zip = ZipFile.Read(LocalCatalogZip))
        {
            zip["ListingExport.txt"].Extract(data);
        }
        data.Seek(0, SeekOrigin.Begin);
        return data;
    }

Это не библиотеку, которую вы используете сейчас, но если вы можете ее изменить, вы можете получить эту функциональность.


Вот вариант, который возвращает Dictionary<string,MemoryStream> для содержимого каждого файла zip файл.

    private static Dictionary<string,MemoryStream> UnZipToMemory()
    {
        var result = new Dictionary<string,MemoryStream>();
        using (ZipFile zip = ZipFile.Read(LocalCatalogZip))
        {
            foreach (ZipEntry e in zip)
                            {
                                MemoryStream data = new MemoryStream();
                                e.Extract(data);
                                result.Add(e.FileName, data);
                            }
        }
        return result;
    }
12
ответ дан Bobson 26 August 2018 в 02:09
поделиться

У меня была аналогичная проблема, и ответ, который я считаю довольно элегантным, заключается в использовании #ZipLib (доступно с помощью nuget) и выполните следующие действия:

private byte[] GetUncompressedPayload(byte[] data)
{
    using (var outputStream = new MemoryStream())
    using (var inputStream = new MemoryStream(data))
    {
        using (var zipInputStream = new ZipInputStream(inputStream))
        {
            zipInputStream.GetNextEntry();
            zipInputStream.CopyTo(outputStream);
        }
        return outputStream.ToArray();
    }
}

Кажется, это сработало. Надеюсь, это поможет.

8
ответ дан kipper_t 26 August 2018 в 02:09
поделиться

Да, .Net 4.5 теперь поддерживает больше функций Zip .

Вот пример кода, основанный на вашем описании.

В вашем проекте щелкните правой кнопкой мыши папку «Ссылки» и добавьте ссылку на System.IO.Compression

using System.IO.Compression;

Stream data = new MemoryStream(); // The original data
Stream unzippedEntryStream; // Unzipped data from a file in the archive

ZipArchive archive = new ZipArchive(data);
foreach (ZipArchiveEntry entry in archive.Entries)
{
    if(entry.FullName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
         unzippedEntryStream = entry.Open(); // .Open will return a stream
         // Process entry data here
    }
}

. Надеюсь, это поможет.

74
ответ дан Mark Amery 26 August 2018 в 02:09
поделиться

Да. Измените использование FastZip на new ZipFile(stream), но это работает только в том случае, если ваш поток может искать. (Просто используйте свой MemoryStream в new ZipFile(fs); вместо чтения потока файлов, как в примере.)

C#
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

public void ExtractZipFile(string archiveFilenameIn, string password, string outFolder) {
    ZipFile zf = null;
    try {
        FileStream fs = File.OpenRead(archiveFilenameIn);
        zf = new ZipFile(fs);
        if (!String.IsNullOrEmpty(password)) {
            zf.Password = password;     // AES encrypted entries are handled automatically
        }
        foreach (ZipEntry zipEntry in zf) {
            if (!zipEntry.IsFile) {
                continue;           // Ignore directories
            }
            String entryFileName = zipEntry.Name;
            // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
            // Optionally match entrynames against a selection list here to skip as desired.
            // The unpacked length is available in the zipEntry.Size property.

            byte[] buffer = new byte[4096];     // 4K is optimum
            Stream zipStream = zf.GetInputStream(zipEntry);

            // Manipulate the output filename here as desired.
            String fullZipToPath = Path.Combine(outFolder, entryFileName);
            string directoryName = Path.GetDirectoryName(fullZipToPath);
            if (directoryName.Length > 0)
                Directory.CreateDirectory(directoryName);

            // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
            // of the file, but does not waste memory.
            // The "using" will close the stream even if an exception occurs.
            using (FileStream streamWriter = File.Create(fullZipToPath)) {
                StreamUtils.Copy(zipStream, streamWriter, buffer);
            }
        }
    } finally {
        if (zf != null) {
            zf.IsStreamOwner = true; // Makes close also shut the underlying stream
            zf.Close(); // Ensure we release resources
        }
    }
}

Если вы используете поток без поиска, используйте ZipInputStream.

// Calling example:
    WebClient webClient = new WebClient();
    Stream data = webClient.OpenRead("http://www.example.com/test.zip");
    // This stream cannot be opened with the ZipFile class because CanSeek is false.
    UnzipFromStream(data, @"c:\temp");

public void UnzipFromStream(Stream zipStream, string outFolder) {

    ZipInputStream zipInputStream = new ZipInputStream(zipStream);
    ZipEntry zipEntry = zipInputStream.GetNextEntry();
    while (zipEntry != null) {
        String entryFileName = zipEntry.Name;
        // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
        // Optionally match entrynames against a selection list here to skip as desired.
        // The unpacked length is available in the zipEntry.Size property.

        byte[] buffer = new byte[4096];     // 4K is optimum

        // Manipulate the output filename here as desired.
        String fullZipToPath = Path.Combine(outFolder, entryFileName);
        string directoryName = Path.GetDirectoryName(fullZipToPath);
        if (directoryName.Length > 0)
            Directory.CreateDirectory(directoryName);

        // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
        // of the file, but does not waste memory.
        // The "using" will close the stream even if an exception occurs.
        using (FileStream streamWriter = File.Create(fullZipToPath)) {
            StreamUtils.Copy(zipInputStream, streamWriter, buffer);
        }
        zipEntry = zipInputStream.GetNextEntry();
    }
}

Примеры, взятые из ICSharpCode Wiki

4
ответ дан Scott Chamberlain 26 August 2018 в 02:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: