Обработка файлов 7z как потоков .NET - PullRequest
10 голосов
/ 14 сентября 2010

Я бы хотел объединить несколько потоковых операций (например, загрузить файл, распаковать его на лету и обработать данные без каких-либо временных файлов). Файлы в формате 7z. Доступен LZMA SDK, но он заставляет меня создавать внешний выходной поток, а не сам поток - иными словами, прежде чем я смогу с ним работать, выходной поток должен быть полностью записан. SevenZipSharp также, похоже, не хватает этой функциональности.

Кто-нибудь делал что-то подобное?

// in pseudo-code - CompressedFileStream derives from Stream
foreach (CompressedFileStream f in SevenZip.UncompressFiles(Web.GetStreamFromWeb(url))
{
    Console.WriteLine("Processing file {0}", f.Name);
    ProcessStream( f ); // further streaming, like decoding, processing, etc
}

Каждый файловый поток будет вести себя как поток для однократного чтения, представляющий один файл, и вызов MoveNext () в основном сжатом потоке автоматически сделает недействительным и пропустит этот файл.

Подобные конструкции могут быть сделаны для сжатия. Пример использования - выполнить некоторую агрегацию для очень большого количества данных - для каждого файла 7z в каталоге, для каждого файла внутри, для каждой строки данных в каждом файле, суммировать некоторое значение.

ОБНОВЛЕНИЕ 2012-01-06

# ziplib (SharpZipLib) уже делает именно то, что мне нужно для zip-файлов класса ZipInputStream. Вот пример, который выдает все файлы в виде неисследимых потоков внутри данного zip-файла. Все еще ищу решение 7z.

IEnumerable<Stream> UnZipStream(Stream stream)
{
    using (var zipStream = new ZipInputStream(stream))
    {
        ZipEntry entry;
        while ((entry = zipStream.GetNextEntry()) != null)
            if (entry.IsFile)
                yield return zipStream;
    }
}

1 Ответ

0 голосов
/ 29 августа 2011

Базовый алгоритм и параметры, указанные во время сжатия, определяют размер используемых чанков, и нет никакого способа гарантировать, что при декодировании чанков они попадают на границы слова / строки.Таким образом, вам придется полностью распаковать файл перед обработкой.

То, что вы просите сделать, это , вероятно, невозможно без временных файлов - от этого зависит, действительно ли у вас достаточно памятичтобы сохранить распакованный файл открытым через MemoryStream, выполните всю вашу обработку и затем освободите память обратно в пул.Еще более усложняет это фрагментация (памяти процесса), которую вы могли бы вызывать, делая это неоднократно.

...