Как определить размер строки и сжать ее - PullRequest
6 голосов
/ 04 мая 2010

В настоящее время я разрабатываю приложение на C #, которое использует Amazon SQS Предельный размер сообщения составляет 8 КБ.

У меня есть метод, который похож на:

public void QueueMessage(string message)

В рамках этого метода я хотел бы, прежде всего, сжать сообщение (большинство сообщений передаются как json, поэтому они уже довольно малы)

Если сжатая строка по-прежнему превышает 8 КБ, я сохраню ее на S3.

Мой вопрос:

Как я могу легко проверить размер строки и как лучше ее сжать? Я не ищу масштабных сокращений в размерах, просто что-то приятное и простое - и легко распаковать другой конец.

Ответы [ 2 ]

12 голосов
/ 04 мая 2010

Чтобы узнать «размер» (в КБ) строки, нам нужно знать кодировку. Если мы предположим UTF8, то это (не включая спецификацию и т. Д.), Как показано ниже (но поменяйте местами кодировку, если это не UTF8):

int len = Encoding.UTF8.GetByteCount(longString);

переупаковка; Я бы предложил GZIP через UTF8, за которым может следовать base-64, если это должна быть строка:

    using (MemoryStream ms = new MemoryStream())
    {
        using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))
        {
            byte[] raw = Encoding.UTF8.GetBytes(longString);
            gzip.Write(raw, 0, raw.Length);
            gzip.Close();
        }
        byte[] zipped = ms.ToArray(); // as a BLOB
        string base64 = Convert.ToBase64String(zipped); // as a string
        // store zipped or base64
    }
1 голос
/ 13 апреля 2012

Дайте распаковать байты этой функции. Лучшее, что я мог придумать, было

public static byte[] ZipToUnzipBytes(byte[] bytesContext)
        {
            byte[] arrUnZipFile = null;
            if (bytesContext.Length > 100)
            {
                using (var inFile = new MemoryStream(bytesContext))
                {
                    using (var decompress = new GZipStream(inFile, CompressionMode.Decompress, false))
                    {
                        byte[] bufferWrite = new byte[4];
                        inFile.Position = (int)inFile.Length - 4;
                        inFile.Read(bufferWrite, 0, 4);
                        inFile.Position = 0;
                        arrUnZipFile = new byte[BitConverter.ToInt32(bufferWrite, 0) + 100];
                        decompress.Read(arrUnZipFile, 0, arrUnZipFile.Length);
                    }
                }
            }
            return arrUnZipFile;
        }
...