我从这里下载了SDK7zip。
然后,我使用这个代码将一个文件压缩为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.6MB压缩到239 KB。
但是,如果我使用WinRar或7zip解压缩。它们无法识别存档文件,错误如下
“未知存档文件或损坏文件”
有什么好主意吗?
发布于 2011-12-01 02:35:23
您可以尝试使用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);
}
发布于 2011-12-01 02:08:43
您看过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);
因此,看起来您需要先写出几个文件头,以便给出即将到来的压缩数据的详细信息。
如果下载7 7Zip的资料来源,那么您会发现文档文件夹中有一个文件7zFormat.txt
,其中包含了对7个zip文件格式的描述。这可能会帮助您创建有效的档案。
发布于 2011-12-01 01:52:09
它在Stream
级别运行的事实表明,它只是在执行lzm压缩/解压缩逻辑,而不是构建实际的存档(存档将是.zip或.7z文件)。类似于使用GZipStream
或DeflateStream
,它没有生成存档。像WinRar和7zip这样的工具可以在档案上工作。
我预计该API中还有另一种类型,它实际上生成一个归档文件,但需要更多的信息,比如文件名(它几乎肯定也会接受多个文件/流)。
https://stackoverflow.com/questions/8339179
复制