我想压缩一个 1.7Kb 的 txt 文件,其中只有数字字符串。数据只是读取不同电压下的电流(100 个条目) 想要压缩并将其写入只有 512 位内存的智能卡中。任何人都可以帮助使用 C# 中可用的压缩技术。我已经尝试过 gzip n Lzman 常见的技术,例如差异机制,但我只能达到 1kb。请在 C# 中提供一些解决方案
4 回答
GZipStream
给你一个比你预期更大的文件的原因是它GZipStream
产生了整个存档文件,而不仅仅是输入的压缩等价物。改为使用DeflateStream
,您将使用完全相同的算法压缩到大小的一小部分。
编辑#2:但是,这将为您节省不超过 144 位的数据,而且对您来说还不够好。压缩文件对于一个小文件来说太大了,因为 Huffman 表的大小是恒定的,而微软的有缺陷的实现。DotNetZip 具有相同的格式,但问题不同。或者您也可以使用SharpZipLib
它支持另一种有趣的算法(格式)(bzip2);用于SetLevel(9)
强制库可以为您提供的最大压缩级别。
Mark Adler在这个答案中很好地解释了为什么 Microsoft 压缩对您如此糟糕,以及为什么 DotNetZip 或 SharpZipLib 即使使用相同的格式(基本算法)也能做得更好。
一种解决方案可能是将数据存储为二进制 => 100 个条目,4 个字节/条目 => 400 个字节。然后,也许,你可以压缩结果。
List<float> myNumbers = ...
MemoryStream ms = new MemoryStream();
using(BinaryWriter bw = new BinaryWriter(stream))
{
foreach(var n in myNumbers)
bw.Write(n);
}
ms.Seek(0, SeekOrigin.Begin);
// Read the first 20 bytes from the stream.
byteArray = new byte[ms.Length];
count = memStream.Read(byteArray, 0, ms.Length);
File.WriteAllBytes(path, byteArray);
并阅读:
byte[] content = File.ReadAllBytes(path);
var ms = new MemoryStream(content);
List<float> result = new List<float>()
using(BinaryReader br = new BinaryReader(ms))
{
result.Add(br.ReadSingle());
}
100 个条目的 512 位意味着每个条目大约 5 位。你要无损地处理这样的事情(我假设你需要)的唯一方法是,如果数据在样本之间具有一些显着的可预测性,因此预测和实际之间的差异足够小,可以平均编码在 5 位。否则就没有希望了。
我确信您可以将其压缩到远小于 1.7KB。如果它真的只有数字(尽管我想知道你有什么令人难以置信的测量设备,每个样本需要 17 位数字),那么你应该能够将它降低到大约 700 个字节。
如果你用它们的实际准确性来表示你的样本,那么你应该能够把数字降低很多。每个样本可能有五位数?然后你可以接近 200 个字节。虽然距离 64 字节(512 位)还有很长的路要走。
您可以使用7ZipSharp库。这非常有效:)