使用7zip sdk压缩文件,但无法使用winrar或7zip解压

发布于 2024-12-19 11:05:06 字数 699 浏览 2 评论 0原文

我从此处下载了 SDK 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 beta。

压缩似乎可以将我的文件从 1.6 MB 压缩到 239 KB。

但是,如果我使用WinRar或7zip来解压。他们无法识别存档文件,错误如下

“未知的存档文件或损坏的文件”

对此有什么想法吗?

I downloaded the SDK 7zip from here.

Then I used this code to compress a file to 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();
    }
}

I tried both the SDK versions 9.20 and 9.22 beta on the site.

The compression seems working to compress my file from: 1.6 MB to 239 KB.

However, if I use WinRar or 7zip to decompress. the archive file is not recognized by them, the error is like

"unknown archive file or damaged file"

Any idea for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云淡风轻 2024-12-26 11:05:06

您看过 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);

因此看起来您需要首先写出一些文件头以提供有关即将到来的压缩数据的详细信息。

如果您下载 7Zip 源代码,那么您会发现doc 文件夹中有一个文件 7zFormat.txt,其中包含 7 个 zip 文件格式的描述。这可能会帮助您创建有效的档案。

have you looked at the example project included with the SDK? It is in the CS\7zip\Compress\LzmaAlone\ folder and it contains a file LmzaAlone.cs which has some stuff which encodes a file. It does things like this before it writes out the compressed data:

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);

so it looks like you need to write out a few file headers first to give the details about the compression data that is coming.

if you download the source for 7Zip then you will find that in the doc folder there is a file 7zFormat.txt which contains a description of the format of the 7 zip files. This might help you create valid archives.

凶凌 2024-12-26 11:05:06

它在 Stream 级别运行的事实表明它只是执行 lzm 压缩/解压缩逻辑,而不是构建实际的存档(存档将是 .zip 或 .7z 文件)。与使用 GZipStream 或 DeflateStream 类似 - 它不会生成存档。 WinRar 和 7zip 等工具可用于处理存档。

我预计该 API 中还有另一种类型实际上会生成存档,但会期望更多信息,例如文件名(它几乎肯定也会接受多个文件/流)。

The fact that it is operating at the Stream level suggests it is just doing the lzm compress/decompress logic, and is not building an actual archive (an archive would be a .zip or .7z file). Similar to using GZipStream or DeflateStream - it isn't producing an archive. Tools like WinRar and 7zip work on archives.

I expect there is another type in that API that actually produces an archive, but will expect more information such as file names (it will almost certainly accept multiple files/streams, too).

九歌凝 2024-12-26 11:05:06

您可以尝试使用 7zSharp 包装器 或至少分析包装器代码如何完成所有操作。

压缩文件的代码(取自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);
  }

You can try to use 7zSharp wrapper or at least analyze wrappers code how everything is done.

Code to compress file(taken from 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);
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文