Jestem nowicjuszem w .net. Robię ciąg kompresji i dekompresji w C #. Istnieje XML i konwertuję na ciąg, a następnie wykonuję kompresję i dekompresję.Nie ma błędu kompilacji w moim kodzie, z wyjątkiem sytuacji, gdy dekompresuję mój kod i zwracam ciąg, zwracając tylko połowę XML.
Poniżej znajduje się mój kod, popraw mnie tam, gdzie się mylę.
Kod:
class Program
{
public static string Zip(string value)
{
//Transform string into byte[]
byte[] byteArray = new byte[value.Length];
int indexBA = 0;
foreach (char item in value.ToCharArray())
{
byteArray[indexBA++] = (byte)item;
}
//Prepare for compress
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.Compression.GZipStream sw = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);
//Compress
sw.Write(byteArray, 0, byteArray.Length);
//Close, DO NOT FLUSH cause bytes will go missing...
sw.Close();
//Transform byte[] zip data to string
byteArray = ms.ToArray();
System.Text.StringBuilder sB = new System.Text.StringBuilder(byteArray.Length);
foreach (byte item in byteArray)
{
sB.Append((char)item);
}
ms.Close();
sw.Dispose();
ms.Dispose();
return sB.ToString();
}
public static string UnZip(string value)
{
//Transform string into byte[]
byte[] byteArray = new byte[value.Length];
int indexBA = 0;
foreach (char item in value.ToCharArray())
{
byteArray[indexBA++] = (byte)item;
}
//Prepare for decompress
System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray);
System.IO.Compression.GZipStream sr = new System.IO.Compression.GZipStream(ms,
System.IO.Compression.CompressionMode.Decompress);
//Reset variable to collect uncompressed result
byteArray = new byte[byteArray.Length];
//Decompress
int rByte = sr.Read(byteArray, 0, byteArray.Length);
//Transform byte[] unzip data to string
System.Text.StringBuilder sB = new System.Text.StringBuilder(rByte);
//Read the number of bytes GZipStream red and do not a for each bytes in
//resultByteArray;
for (int i = 0; i < rByte; i++)
{
sB.Append((char)byteArray[i]);
}
sr.Close();
ms.Close();
sr.Dispose();
ms.Dispose();
return sB.ToString();
}
static void Main(string[] args)
{
XDocument doc = XDocument.Load(@"D:\RSP.xml");
string val = doc.ToString(SaveOptions.DisableFormatting);
val = Zip(val);
val = UnZip(val);
}
}
Mój rozmiar XML to 63 KB.
c#
string
.net-2.0
compression
Mohit Kumar
źródło
źródło
using
.Encoding
niewłaściwego sposobu. Potrzebujesz tutaj bazy 64, zgodnie z odpowiedzią xanatosaOdpowiedzi:
Kod do kompresji / dekompresji ciągu
Pamiętaj, że
Zip
zwraca abyte[]
, whileUnzip
zwraca astring
. Jeśli chcesz napisać odZip
siebie, możesz zakodować go w Base64 (na przykład za pomocąConvert.ToBase64String(r1)
) (wynikZip
jest BARDZO binarny! Nie jest to coś, co możesz wydrukować na ekranie lub napisać bezpośrednio w XML)Sugerowana wersja jest przeznaczona dla .NET 2.0, dla .NET 4.0 użyj rozszerzenia
MemoryStream.CopyTo
.WAŻNE: Skompresowana zawartość nie może zostać zapisana w strumieniu wyjściowym, dopóki nie będzie
GZipStream
wiadomo, że ma wszystkie dane wejściowe (tj. Aby skutecznie skompresować, potrzebuje wszystkich danych). Musisz się upewnić, że jesteśDispose()
wGZipStream
przed sprawdzeniem strumienia wyjściowego (npmso.ToArray()
.). Odbywa się to za pomocąusing() { }
powyższego bloku. Zauważ, żeGZipStream
jest to najbardziej wewnętrzny blok, a dostęp do zawartości jest poza nim. To samo odnosi się do dekompresji:Dispose()
zGZipStream
przed próbą dostępu do danych.źródło
string s = "X\uD800Y"
. Zauważyłem, że działa, jeśli zmienimy kodowanie na UTF7 ... ale czy w przypadku UTF7 jesteśmy pewni, że wszystkie znaki mogą być reprezentowane?zgodnie z tym fragmentem kodu używam tego kodu i działa dobrze:
źródło
Wraz z pojawieniem się .NET 4.0 (i wyższych) z metodami Stream.CopyTo () pomyślałem, że opublikuję zaktualizowane podejście.
Myślę również, że poniższa wersja jest przydatna jako wyraźny przykład niezależnej klasy do kompresji zwykłych ciągów do ciągów zakodowanych w Base64 i odwrotnie:
Oto inne podejście wykorzystujące technikę metod rozszerzających do rozszerzenia klasy String w celu dodania kompresji i dekompresji ciągów. Możesz upuścić poniższą klasę do istniejącego projektu, a następnie użyć w ten sposób:
i
Dowcip:
źródło
using
instrukcji dla instancji MemoryStream. A do programistów F #: powstrzymaj się od używania słowa kluczowegouse
dla instancji compressStream / decompressorStream, ponieważ muszą zostać usunięte ręcznie, zanim zostanąToArray()
wywołaneTo jest zaktualizowana wersja dla .NET 4.5 i nowszych przy użyciu async / await i IEnumerables:
Dzięki temu możesz serializować wszystko
BinaryFormatter
, co obsługuje, zamiast tylko ciągów.Edytować:
Na wypadek, gdybyś musiał się tym zająć
Encoding
, możesz po prostu użyć Convert.ToBase64String (byte []) ...Spójrz na tę odpowiedź, jeśli potrzebujesz przykładu!
źródło
Convert.ToBase64String(byte[])
. Zapoznaj się z tą odpowiedzią ( stackoverflow.com/a/23908465/3286975 ). Mam nadzieję, że to pomoże!Dla tych, którzy nadal otrzymują Magiczna liczba w nagłówku GZip jest nieprawidłowa. Upewnij się, że przekazujesz strumień GZip. BŁĄD i jeśli twój ciąg został spakowany za pomocą php , musisz zrobić coś takiego:
źródło