Recement je stockais dans une colonne varchar(max) d’une base de données tout un arbre xml, la taille etait montée à pratiquement 500ko, ce qui provoquait des ralentissements lors du chargement des données.
pour accelerer le chargement j’ai décidé de zipper le contenu au moment de sauvegarder et de dezipper au chargement.
J’ai utilisé les methodes d’extensions suivantes pour réaliser cette opération :
/// <summary>
/// zip the base64 input string to string.
/// </summary>
/// <param name="input">The input.</param>
/// <returns></returns>
public static string GZipToBase64String(this string input)
{
string result = null;
using (var ms = new System.IO.MemoryStream())
{
var buffer = System.Text.Encoding.UTF8.GetBytes(input);
using (var zip = new System.IO.Compression.GZipStream(ms, CompressionMode.Compress, true))
{
zip.Write(buffer, 0, buffer.Length);
zip.Close();
}
result = Convert.ToBase64String(ms.ToArray());
ms.Close();
}
return result;
}
/// <summary>
/// UnZip zippedBuffer
/// </summary>
/// <param name="zippedbuffer">The zippedbuffer.</param>
/// <returns></returns>
public static string UnGZip(this byte[] zippedbuffer)
{
string result = null;
int blockSize = 512;
using (var compressedStream = new System.IO.MemoryStream(zippedbuffer, false))
{
if (compressedStream.CanSeek)
{
compressedStream.Seek(0, SeekOrigin.Begin);
}
using (var uncompressedStream = new System.IO.MemoryStream())
{
using (var unzip = new System.IO.Compression.GZipStream(compressedStream, CompressionMode.Decompress))
{
var bf = new byte[blockSize];
while (true)
{
// Bug ! if zippedbuffer smaller than 4096 bytes, read byte one by one
if (zippedbuffer.Length <= 4096)
{
var pos = unzip.ReadByte();
if (pos == -1)
{
break;
}
uncompressedStream.WriteByte((byte)pos);
}
else
{
var count = unzip.Read(bf, 0, blockSize);
if (count == 0)
{
break;
}
uncompressedStream.Write(bf, 0, count);
}
}
result = System.Text.Encoding.UTF8.GetString(uncompressedStream.ToArray());
unzip.Close();
}
uncompressedStream.Close();
}
compressedStream.Close();
}
return result;
}
/// <summary>
/// unzip base64 zipped string.
/// </summary>
/// <param name="input">The input.</param>
/// <returns></returns>
public static string UnGZipFromBase64String(this string zippedinput)
{
var buffer = Convert.FromBase64String(zippedinput);
return buffer.UnGZip();
}
Il y a un bug plutot incompréhensible si le contenu à dezipper de inférieur a 4096, alors il faut lire les bytes 1 par 1, pas très efficace au niveau perf.
Exemple d’utilisation des methodes :
var content = “ceci est un message de test juste pour l’exemple”;
var zipped = content.GZipToBase64String();
retourne une chaine de caractère encodé en base64
var unzipped = zipped.UnGZipFromBase64String();
retourne la chaine initiale
Aucun commentaire:
Enregistrer un commentaire