2010-05-04 3 views
6

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

У меня есть метод, который что-то вроде:

public void QueueMessage(string message) 

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

Если сжатая строка все еще больше 8 КБ, я буду хранить ее на S3.

Мой вопрос:

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

ответ

12

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

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

Re упаковка его; Я хотел бы предложить GZIP через UTF8, необязательно с последующим основанием-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 
    } 
+0

Спасибо , Как определить кодировку? Я не задал это нигде ... Я просто сериализую объект для json (используя json.net lib) – Alex

+0

Вопрос: нужен ли 'gzip.Close()' вызов, учитывая, что выход из блока 'using' должен закрыть его так или иначе? – tzaman

+0

@alex: Вы сами выбрали кодировку, когда сериализуете строку в двоичную. Как говорит Марк, UTF-8 - лучший выбор для размера, поскольку большинство символов занимают только один байт в этой кодировке. –

1

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

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; 
     } 
Смежные вопросы