2010-09-14 3 views
10

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

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

// 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-файла в каталоге, для каждого файла внутри, для каждой строки данных в каждом файле суммируйте некоторое значение.

UPDATE 2012-01-06

#ziplib (SharpZipLib) уже делает именно то, что мне нужно для архивных файлов с 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; 
    } 
} 

ответ

0

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

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

+0

Я не уверен, что понимаю, что вы подразумеваете под словом/границей. Объект 'CompressedFileStream' возвращается в тот момент, когда SevenZip получает заголовок файла из потока, а не после получения всего файла. Чтение распакованных файлов приводит к тому, что поток источника также продвигается вперед. – Yurik