Mam duży obiekt w pamięci, który chcę zapisać jako blob w bazie danych. Chcę skompresować go przed zapisaniem, ponieważ serwer bazy danych zwykle nie jest lokalny.Jak serializować obiekt + skompresować go, a następnie rozpakować + deserializować bez biblioteki innej firmy?
To jest to, co mam w tej chwili:
using (var memoryStream = new MemoryStream())
{
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(gZipStream, obj);
return memoryStream.ToArray();
}
}
Jednak kiedy zip same bajty z Total Commander to zmniejszają wielkość zawsze o 50% co najmniej. Z powyższym kodem kompresuje 58MB do 48MB, a wszystko poniżej 15MB staje się jeszcze większe.
Czy powinienem używać zewnętrznej biblioteki zip lub czy jest lepszy sposób na zrobienie tego w .NET 3.5. Jakieś inne alternatywy dla mojego problemu?
EDIT:
Właśnie znalazłeś błąd w kodzie powyżej. Angelo dzięki za poprawkę.
Kompresja GZipStream nadal nie jest świetna. Mam średnią kompresję 35% według gZipStream w porównaniu do kompresji 48% TC.
nie mam pojęcia jakie bajtów Byłem wysiadając z poprzedniej wersji :)
EDIT2:
znalazłem sposobu poprawy kompresji od 20% do 47%. Musiałem użyć dwóch strumieni pamięci zamiast jednego! Czy ktoś może wyjaśnić, dlaczego tak się dzieje?
Oto kod z 2 strumieniami pamięci, który ma znacznie lepszą kompresję !!!
using (MemoryStream msCompressed = new MemoryStream())
using (GZipStream gZipStream = new GZipStream(msCompressed, CompressionMode.Compress))
using (MemoryStream msDecompressed = new MemoryStream())
{
new BinaryFormatter().Serialize(msDecompressed, obj);
byte[] byteArray = msDecompressed.ToArray();
gZipStream.Write(byteArray, 0, byteArray.Length);
gZipStream.Close();
return msCompressed.ToArray();
}
Używam http: //www.icsharpcode.net/opensource/sharpziplib/Download.aspx z dużym sukcesem. – Asken