2010-05-04 11 views
6

Ich entwickle gerade eine Anwendung in C#, die Amazon SQS verwendet Die Größenbeschränkung für eine Nachricht beträgt 8 KB.So ermitteln Sie die Größe der Zeichenfolge und komprimieren Sie sie

Ich habe eine Methode, die so etwas wie ist:

public void QueueMessage(string message) 

Innerhalb dieser Methode würde ich vor allem gerne, komprimieren die Nachricht (die meisten Mitteilungen werden als json eingeleitet, so sind schon ziemlich klein)

Wenn die komprimierte Zeichenfolge immer noch größer als 8 KB ist, werde ich es in S3 speichern.

Meine Frage ist:

Wie kann ich die Größe eines Strings einfach testen, und was ist der beste Weg, es zu komprimieren? Ich bin nicht auf der Suche nach massiven Verkleinerungen, einfach etwas Schönes und Einfaches - und einfach das andere Ende zu dekomprimieren.

Antwort

12

Um die "Größe" (in kb) eines Strings zu kennen, müssen wir die Codierung kennen. Wenn wir UTF8 annehmen, dann ist es (ohne BOM usw.) wie unten (aber die Codierung tauschen, wenn es nicht UTF8 ist):

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

Re Verpackung es; Ich würde GZIP über UTF8 vorschlagen, gegebenenfalls mit Base-64 gefolgt, wenn es sich um eine Zeichenfolge sein muss:

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

Dank einfiel . Wie ermittle ich die Codierung? Ich habe das nirgendwo festgelegt ... ich serialisieren nur ein Objekt zu json (mit der json.net-lib) – Alex

+0

Frage: ist der 'gzip.Close()' Aufruf notwendig, wenn man bedenkt, dass 'using' Block beendet wird, sollte es schließen sowieso? – tzaman

+0

@alex: Sie würden die Codierung selbst auswählen, wenn Sie die Zeichenfolge in Binärcode serialisieren. Wie Marc sagt, ist UTF-8 die beste Wahl für die Größe, da die meisten Zeichen in dieser Kodierung nur ein Byte belegen. –

1

Geben unzip Bytes dieser function.the besten, die ich mit war

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; 
     }