【发布时间】:2021-05-05 05:05:25
【问题描述】:
我想将一个字符串(任何大小),如“你好,我的名字是 Bob,我做得很好”,压缩成一个较小的字符串,如“jg3K9dlj”。并且能够解压回来。 Input 和 Output 应该都是两个字符串。
我发现这个代码很容易使用:2 个函数 Compress() 和 Decompress()。 不幸的是,结果它给出了更长的字符串。 我还发现了其他使用 Bytes Array 但无法将它们显示为字符串的示例(完全不可读)。每次我使用 Convert.ToBase64String(bytes) 时也是如此,然后我们得到一个比原始字符串更长的字符串。感谢您的任何建议!
public static string Compress(string uncompressedString)
{
byte[] compressedBytes;
using (var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(uncompressedString)))
{
using (var compressedStream = new MemoryStream())
{
// setting the leaveOpen parameter to true to ensure that compressedStream will not be closed when compressorStream is disposed
// this allows compressorStream to close and flush its buffers to compressedStream and guarantees that compressedStream.ToArray() can be called afterward
// although MSDN documentation states that ToArray() can be called on a closed MemoryStream, I don't want to rely on that very odd behavior should it ever change
using (var compressorStream = new DeflateStream(compressedStream, CompressionLevel.Fastest, true))
{
uncompressedStream.CopyTo(compressorStream);
}
// call compressedStream.ToArray() after the enclosing DeflateStream has closed and flushed its buffer to compressedStream
compressedBytes = compressedStream.ToArray();
}
}
return Convert.ToBase64String(compressedBytes);
}
public static string Decompress(string compressedString)
{
byte[] decompressedBytes;
var compressedStream = new MemoryStream(Convert.FromBase64String(compressedString));
using (var decompressorStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
{
using (var decompressedStream = new MemoryStream())
{
decompressorStream.CopyTo(decompressedStream);
decompressedBytes = decompressedStream.ToArray();
}
}
return Encoding.UTF8.GetString(decompressedBytes);
}
【问题讨论】:
-
你必须使用直接对字符串进行操作的压缩算法。
-
请记住:压缩有一定的开销。因此,对于非常小的输入,通常压缩增益很可能超过该开销。你对此无能为力。除了了解压缩仅适用于 更大 数量的数据。 (作为进一步阅读,我推荐The Pigeonhole Principle)
-
您可以尝试使用预训练字典的 zlib,但我不知道 C# 实现。有关的; stackoverflow.com/questions/479218/…
-
@FranzGleichmann 鸽巢原则不适用于 string => byte[] 压缩。由于某些 byte[] 序列不是有效的 unicode 字符串,因此应该可以确保“压缩”字节数组永远不会比输入字符串长。
-
@JeremyLakeman 鸽巢原则适用于 every 压缩。因为最后,您将一组字节压缩为另一组字节 - “字符串”只是它之上的抽象。
标签: c# string compression