Я пытаюсь сжать строку как можно больше.У меня есть код, который работает при сжатии до строки Base64 и распаковке из строки Base64.
public static string CompressString(string text)
{
byte[] buffer = Encoding.UTF8.GetBytes(text);
var memoryStream = new MemoryStream();
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
{
gZipStream.Write(buffer, 0, buffer.Length);
}
memoryStream.Position = 0;
var compressedData = new byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length);
var gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
return Convert.ToBase64String(gZipBuffer); // RETURNS AS BASE64
//return Encoding.UTF8.GetString(gZipBuffer); // RETURN AS UTF8 STRING
}
public static string DecompressString(string compressedText)
{
byte[] gZipBuffer = Convert.FromBase64String(compressedText); // BASE64 STRING TO BYTE ARRAY
//byte[] gZipBuffer = Encoding.UTF8.GetBytes(compressedText); // UTF8 STRING TO BYTE ARRAY
using (var memoryStream = new MemoryStream())
{
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);
var buffer = new byte[dataLength];
memoryStream.Position = 0;
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
gZipStream.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
}
Это прекрасно работает.Однако, если я переключаю CompressString
, чтобы вернуть Encoding.UTF8.GetString(gZipBuffer)
вместо Convert.ToBase64String(gZipBuffer)
, и меняю DecompressString
для чтения в буфер, используя Encoding.UTF8.GetBytes(compressedText)
вместо Convert.FromBase64String(compressedText)
, я получаю исключение при распаковке (хотя сжатие работает нормально).
Additional information: The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
Проблема с использованием Base64 заключается в том, что она приводит к получению окончательной сжатой строки, которая на 40% длиннее, чем при использовании Encoding.UTF8.GetString
и Encoding.UTF8.GetBytes
Можно ли как-нибудь сжать строку без того, чтобы полученная строка была закодирована в base64?