2011-12-01 187 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

相关问题