2011-12-01 136 views
4

我從here下載了SDK 7zip。使用7zip sdk壓縮文件,但無法使用winrar或7zip解壓縮

然後我用這個代碼文件壓縮成7zip的:

private static void CompressFileLZMA(string inFile, string outFile) 
{ 
    Encoder coder = new SevenZip.Compression.LZMA.Encoder(); 

    using (FileStream input = new FileStream(inFile, FileMode.Open)) 
    using (FileStream output = new FileStream(outFile, FileMode.Create)) 
    { 
     coder.Code(input, output, -1, -1, null); 
     output.Flush(); 
    } 
} 

我試用過SDK版本9.20和9.22測試版的網站上。

壓縮似乎正在從我的文件壓縮:1.6 MB到239 KB。

但是,如果我使用WinRar或7zip來解壓縮。存檔文件不被認可他們的錯誤是一樣

「未知歸檔文件或損壞的文件」

任何想法呢?

回答

2

您可以嘗試使用7zSharp wrapper或至少分析包裝代碼如何完成所有工作。

代碼壓縮文件(從7zSharp拍攝):

public void EncodeSingleFile(string inFile, string outFile) 
    { 
    using (FileStream inStream = new FileStream(inFile, FileMode.Open, FileAccess.Read)) 
    { 
     using (FileStream outStream = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write)) 
     { 
      EncodeSingleFile(inStream, outStream); 
     } 
    } 
    } 

    public void EncodeSingleFile(FileStream inStream, FileStream outStream) 
    { 
    bool eos = false; 
    Int32 dictionary = 1 << 21; 
    Int32 posStateBits = 2; 
    Int32 litContextBits = 3; // for normal files 
    // UInt32 litContextBits = 0; // for 32-bit data 
    Int32 litPosBits = 0; 
    // UInt32 litPosBits = 2; // for 32-bit data 
    Int32 algorithm = 2; 
    Int32 numFastBytes = 128; 
    string mf = "bt4"; 

    propIDs = new CoderPropID[] 
     { 
      CoderPropID.DictionarySize, 
      CoderPropID.PosStateBits, 
      CoderPropID.LitContextBits, 
      CoderPropID.LitPosBits, 
      CoderPropID.Algorithm, 
      CoderPropID.NumFastBytes, 
      CoderPropID.MatchFinder, 
      CoderPropID.EndMarker 
     }; 
    properties = new object[] 
     { 
      dictionary, 
      posStateBits, 
      litContextBits, 
      litPosBits, 
      algorithm, 
      numFastBytes, 
      mf, 
      eos 
     }; 

    Encoder encoder = new Encoder(); 
    encoder.SetCoderProperties(propIDs, properties); 
    encoder.WriteCoderProperties(outStream); 
    Int64 fileSize = inStream.Length; 
    for (int i = 0; i < 8; i++) 
    { 
     outStream.WriteByte((Byte) (fileSize >> (8*i))); 
    } 
    encoder.Code(inStream, outStream, -1, -1, null); 
    } 
+0

是的,它有幫助。有了這個包裝器,我可以成功創建一個7zip文件。但是,有兩個問題:1.我只能使用從7-zip.org安裝的7zip shell進行解壓縮,不能使用unrar進行解壓縮。如果我設置了一些參數,那麼它可能會與unrar一起工作嗎? 2.在7zip文件中壓縮後,壓縮文件名不是原始的:例如:我有test.abc,然後將其壓縮爲:compressed7.7z,然後內部的壓縮文件是「壓縮的」,沒有擴展名。它應該是7zip裏面的test.abc。我怎樣才能做到這一點?提前致謝。 – olidev

+0

我認爲這是另一個問題,我在這裏發佈:http://stackoverflow.com/questions/8340636/using-7zip-sdk-to-compress-a-file-but-the-archive-file-is-not -as-original-and -c – olidev

+0

你有沒有任何想法是否有像這樣的包裝使用7zip sdk壓縮目錄以及? – olidev

3

它在Stream級別上運行的事實表明它只是在執行lzm壓縮/解壓縮邏輯,而不是構建實際的歸檔文件(歸檔文件將是.zip或.7z文件)。類似於使用GZipStreamDeflateStream - 它不會生成檔案。 WinRar和7zip等工具可用於檔案。

我期望在該API中有另一種類型,它實際上會生成一個檔案,但是會期望更多的信息,例如文件名(它幾乎肯定會接受多個文件/流)。

+0

我簡單地稱爲像這樣:CompressFileLZMA( 「CompressionTest.pdb」, 「CompressionTestabc.7z」); – olidev

+0

@devn的重點是,CompressFileLZMA是*你的*方法和*你的*方法不是寫出一個有效的檔案,它只是寫出壓縮的數據流到文件。您可以使用api讀取數據流並對其進行解壓縮,但不會生成有效的*存檔文件*,而無需諸如文件頭等額外信息。如果您想壓縮不會看的數據像一個可以在7Zip中打開的檔案,但是你的程序可以讀取。但爲了能夠讀取7Zip或類似的數據,你需要生成一個有效的檔案 –

+0

是的,你是對的!謝謝 – olidev

4

您是否看過SDK附帶的示例項目?它位於CS\7zip\Compress\LzmaAlone\文件夾中,它包含一個文件LmzaAlone.cs,它有一些編碼文件的內容。它做了一些類似這樣的寫入了壓縮數據之前:

CoderPropID[] propIDs = 
{ 
    CoderPropID.DictionarySize, 
    CoderPropID.PosStateBits, 
    CoderPropID.LitContextBits, 
    CoderPropID.LitPosBits, 
    CoderPropID.Algorithm, 
    CoderPropID.NumFastBytes, 
    CoderPropID.MatchFinder, 
    CoderPropID.EndMarker 
}; 
object[] properties = 
{ 
    (Int32)(dictionary), 
    (Int32)(posStateBits), 
    (Int32)(litContextBits), 
    (Int32)(litPosBits), 
    (Int32)(algorithm), 
    (Int32)(numFastBytes), 
    mf, 
    eos 
}; 

Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder(); 
encoder.SetCoderProperties(propIDs, properties); 
encoder.WriteCoderProperties(outStream); 
if (trainStream != null) 
{ 
    CDoubleStream doubleStream = new CDoubleStream(); 
    doubleStream.s1 = trainStream; 
    doubleStream.s2 = inStream; 
    doubleStream.fileIndex = 0; 
    inStream = doubleStream; 
    long trainFileSize = trainStream.Length; 
    doubleStream.skipSize = 0; 
    if (trainFileSize > dictionary) 
     doubleStream.skipSize = trainFileSize - dictionary; 
    trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin); 
    encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize)); 
} 
// only now does it write out the compressed data: 
encoder.Code(inStream, outStream, -1, -1, null); 

,所以它看起來像你需要先寫了幾個文件頭給有關即將到來的壓縮數據的細節。

如果您下載了source for 7Zip,那麼您會發現在doc文件夾中有一個文件7zFormat.txt,其中包含對7個zip文件格式的描述。這可能會幫助您創建有效的檔案。

+0

+ 1的標題,最有可能OP已經忘記把它們。 – oleksii

+0

是的,像這樣添加包裝將幫助 – olidev

相關問題