2010-09-14 26 views
10

Je voudrais enchaîner plusieurs opérations de flux (comme le téléchargement d'un fichier, sa décompression à la volée et le traitement des données sans aucun fichier temporaire). Les fichiers sont au format 7z. Il y a un SDK LZMA disponible, mais cela me force à créer un flux de sortie externe au lieu d'être un flux lui-même - en d'autres termes, le flux de sortie devra être entièrement écrit avant que je puisse travailler avec. SevenZipSharp semble également manquer cette fonctionnalité.Traitement de fichiers 7z en tant que flux .NET

Est-ce que quelqu'un a fait quelque chose comme ça?

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

Chaque flux de fichier se comporte comme une lecture fois flux représentant un fichier, et d'appeler MoveNext() sur le flux principal comprimé serait automatiquement invalider & sauter ce fichier.

Des constructions similaires peuvent être réalisées pour la compression. Exemple d'utilisation - faire une agrégation sur une très grande quantité de données - pour chaque fichier 7z dans un répertoire, pour chaque fichier à l'intérieur, pour chaque ligne de données dans chaque fichier, résumez une certaine valeur.

MISE À JOUR 2012-01-06

#ziplib (SharpZipLib) fait déjà exactement ce que j'ai besoin pour les fichiers zip avec ZipInputStream classe. Voici un exemple qui donne tous les fichiers sous la forme de flux non inscriptibles dans un fichier zip donné. Toujours à la recherche d'une solution 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; 
    } 
} 

Répondre

0

L'algorithme sous-jacent et les paramètres spécifiés au moment de la compression déterminent la taille des morceaux utilisés et il n'y a aucun moyen de garantir que vous décodez morceaux, ils tombent aux frontières mot/ligne. Donc, vous devrez décompresser complètement un fichier avant de le traiter.

Ce que vous demandez de faire est probablement pas possible sans fichiers temporaires - ce qu'il dépend vraiment est de savoir si vous avez suffisamment de mémoire pour conserver le fichier décompressé ouvert via un MemoryStream, effectuez tous vos traitement et puis relâchez la mémoire Retour à la piscine. La fragmentation (de la mémoire de processus) que vous pourriez provoquer de façon répétée est encore compliquée.

+0

Je ne suis pas sûr de comprendre ce que vous entendez par frontières entre les mots et les lignes. L'objet 'CompressedFileStream' est renvoyé au moment où SevenZip reçoit l'en-tête du fichier, et non après l'obtention du fichier entier. La lecture des données du fichier décompressé fait également avancer le flux source. – Yurik