2016-01-03 79 views
4

LZH歸檔文件嵌入在文件中。該文件被讀入一個字節[],並且LZH部分被識別爲較小的字節[]。在.NET中的字節數組解壓縮LZH?

如何使用.NET Framework 4.6(C#)將嵌入式LZH字節解壓縮到另一個字節[]中?我只看到http://www.infoq.com/news/2008/06/7-Zip-from-.NET這不完全是我所需要的。

謝謝。

+0

我假設你已經看過system.io.compression這不是能夠讀取LZH格式字節 運行?我沒有一個字節數組可以玩,或者我會在詢問之前嘗試一下;) – bri

+0

.NET中的壓縮庫沒有LZH支持。我正在尋找一種託管代碼解決方案,可以在託管的Web環境中安全地運行特殊應用程序。 – Snowy

+0

是的。我認爲system.io.compression太明顯了;-)。從不傷害我想。 – bri

回答

1

隨後從樣本程序取自本文 http://www.codeproject.com/Articles/27148/C-NET-Interface-for-Zip-Archive-DLLs

沒有顯著變化的代碼片段:而不是讀取和寫入文件,讀取和寫入的字節數組。變化是由註釋標記sevenzip.exe e "C:\temp\gwo0.11-sample-win32.lzh" 3例如

https://dl.dropboxusercontent.com/u/71459360/7z.zip

using System; 
using System.Collections.Generic; 
using System.Text; 
using Nomad.Archive.SevenZip; 
using System.IO; 
using System.Runtime.InteropServices; 
using System.Reflection; 

namespace SevenZip 
{ 
    class Program 
    { 
     private static void ShowHelp() 
     { 
      Console.WriteLine("SevenZip"); 
      Console.WriteLine("SevenZip l {ArchiveName}"); 
      Console.WriteLine("SevenZip e {ArchiveName} {FileNumber}"); 
     } 

     static void Main(string[] args) 
     { 
      if (args.Length < 2) 
      { 
       ShowHelp(); 
       return; 
      } 

      try 
      { 
       string ArchiveName; 
       uint FileNumber = 0xFFFFFFFF; 
       bool Extract; 

       switch (args[0]) 
       { 
        case "l": 
         ArchiveName = args[1]; 
         Extract = false; 
         break; 
        case "e": 
         ArchiveName = args[1]; 
         Extract = true; 
         if ((args.Length < 3) || !uint.TryParse(args[2], out FileNumber)) 
         { 
          ShowHelp(); 
          return; 
         } 
         break; 
        default: 
         ShowHelp(); 
         return; 
       } 

       using (SevenZipFormat Format = new SevenZipFormat(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll"))) 
       { 
        IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.Lzh)); 
        if (Archive == null) 
        { 
         ShowHelp(); 
         return; 
        } 

        try 
        { 
         //the byte array is provided by you. here it's coming from a file 
         byte[] data; 
         using (var stream = File.OpenRead(ArchiveName)) 
         { 
          data = new byte[stream.Length]; 
          stream.Read(data, 0, data.Length); 
         } 

         using (InStreamWrapper ArchiveStream = new InStreamWrapper(new MemoryStream(data))) //modified here 
         { 
          ulong CheckPos = 32 * 1024; 
          if (Archive.Open(ArchiveStream, ref CheckPos, null) != 0) 
           ShowHelp(); 

          Console.Write("Archive: "); 
          Console.WriteLine(ArchiveName); 

          if (Extract) 
          { 
           PropVariant Name = new PropVariant(); 
           Archive.GetProperty(FileNumber, ItemPropId.kpidPath, ref Name); 
           string FileName = (string) Name.GetObject(); 

           Console.Write("Extracting: "); 
           Console.Write(FileName); 
           Console.Write(' '); 

           MemoryStream ms = new MemoryStream(); 
           Archive.Extract(new uint[] { FileNumber }, 1, 0, new ArchiveMemoryCallback(FileNumber, ms)); //modified here 
           byte[] output = ms.ToArray(); //here you have the output byte array 
           output.ToString(); 
          } 
          else 
          { 
           Console.WriteLine("List:"); 
           uint Count = Archive.GetNumberOfItems(); 
           for (uint I = 0; I < Count; I++) 
           { 
            PropVariant Name = new PropVariant(); 
            Archive.GetProperty(I, ItemPropId.kpidPath, ref Name); 
            Console.Write(I); 
            Console.Write(' '); 
            Console.WriteLine(Name.GetObject()); 
           } 
          } 
         } 
        } 
        finally 
        { 
         Marshal.ReleaseComObject(Archive); 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       Console.Write("Error: "); 
       Console.WriteLine(e.Message); 
      } 
     } 
    } 

    class ArchiveCallback : IArchiveExtractCallback 
    { 
     private uint FileNumber; 
     private string FileName; 
     private OutStreamWrapper FileStream; 

     public ArchiveCallback(uint fileNumber, string fileName) 
     { 
      this.FileNumber = fileNumber; 
      this.FileName = fileName; 
     } 

     #region IArchiveExtractCallback Members 

     public void SetTotal(ulong total) 
     { 
     } 

     public void SetCompleted(ref ulong completeValue) 
     { 
     } 

     public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 
     { 
      if ((index == FileNumber) && (askExtractMode == AskMode.kExtract)) 
      { 
       string FileDir = Path.GetDirectoryName(FileName); 
       if (!string.IsNullOrEmpty(FileDir)) 
        Directory.CreateDirectory(FileDir); 
       FileStream = new OutStreamWrapper(File.Create(FileName)); 

       outStream = FileStream; 
      } 
      else 
       outStream = null; 

      return 0; 
     } 

     public void PrepareOperation(AskMode askExtractMode) 
     { 
     } 

     public void SetOperationResult(OperationResult resultEOperationResult) 
     { 
      FileStream.Dispose(); 
      Console.WriteLine(resultEOperationResult); 
     } 

     #endregion 
    } 


    //new 
    class ArchiveMemoryCallback : IArchiveExtractCallback 
    { 
     private uint FileNumber; 
     private Stream stream; 
     private OutStreamWrapper FileStream; 

     public ArchiveMemoryCallback(uint fileNumber, Stream stream) 
     { 
      this.FileNumber = fileNumber; 
      this.stream = stream; 
     } 

     #region IArchiveExtractCallback Members 

     public void SetTotal(ulong total) 
     { 
     } 

     public void SetCompleted(ref ulong completeValue) 
     { 
     } 

     public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 
     { 
      if ((index == FileNumber) && (askExtractMode == AskMode.kExtract)) 
      { 
       FileStream = new OutStreamWrapper(stream); 

       outStream = FileStream; 
      } 
      else 
       outStream = null; 

      return 0; 
     } 

     public void PrepareOperation(AskMode askExtractMode) 
     { 
     } 

     public void SetOperationResult(OperationResult resultEOperationResult) 
     { 
      FileStream.Dispose(); 
      Console.WriteLine(resultEOperationResult); 
     } 

     #endregion 
    } 
} 
+0

在第三方DLL上釋放一個COM鎖存器的元帥使我的目的不可用,對不起。我正在尋找一種在託管.NET中運行的全內存解決方案。 – Snowy

+0

看起來你運氣不好:LZH並非如此流行的壓縮格式,特別是在windows(等.net)上。我從來沒有找到一個可以處理它的已經完全託管的庫。 我可以問爲什麼互動出來的圖片? –

+0

Interop不在圖中,因爲我需要在託管環境中運行,其中所有內容都必須位於Web應用程序的內存空間中。 – Snowy

相關問題