Soy novato en .net. Estoy haciendo una cadena de compresión y descompresión en C #. Hay un XML y estoy convirtiendo en cadena y después de eso estoy haciendo compresión y descompresión. No hay ningún error de compilación en mi código, excepto cuando descomprimo mi código y devuelvo mi cadena, solo devuelve la mitad del XML.
A continuación se muestra mi código, corrígeme donde estoy equivocado.
Código:
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);
}
}
Mi tamaño XML es de 63 KB.
c#
string
.net-2.0
compression
Mohit Kumar
fuente
fuente
using
.Encoding
el camino equivocado. Necesitas base-64 aquí, según la respuesta de xanatosRespuestas:
El código para comprimir / descomprimir una cadena
Recuerde que
Zip
devuelve abyte[]
, mientras queUnzip
devuelve astring
. Si quiere una cadenaZip
, puede codificarla en Base64 (por ejemplo, usandoConvert.ToBase64String(r1)
) (¡el resultadoZip
es MUY binario! No es algo que pueda imprimir en la pantalla o escribir directamente en un XML)La versión sugerida es para .NET 2.0, para .NET 4.0 use el
MemoryStream.CopyTo
.IMPORTANTE: El contenido comprimido no se puede escribir en la secuencia de salida hasta
GZipStream
que sepa que tiene toda la entrada (es decir, para comprimirlo efectivamente necesita todos los datos). Es necesario asegurarse de queDispose()
elGZipStream
antes de inspeccionar el flujo de salida (por ejemplo,mso.ToArray()
). Esto se hace con elusing() { }
bloque de arriba. Tenga en cuenta queGZipStream
es el bloque más interno y se accede a los contenidos fuera de él. Lo mismo vale para descomprimir:Dispose()
de losGZipStream
antes de intentar acceder a los datos.fuente
string s = "X\uD800Y"
. Noté que funciona si cambiamos la codificación a UTF7 ... pero con UTF7, ¿estamos seguros de que todos los caracteres se pueden representar?De acuerdo con este fragmento, uso este código y funciona bien:
fuente
Con la llegada de .NET 4.0 (y superior) con los métodos Stream.CopyTo (), pensé en publicar un enfoque actualizado.
También creo que la siguiente versión es útil como un claro ejemplo de una clase autónoma para comprimir cadenas regulares a cadenas codificadas en Base64, y viceversa:
Aquí hay otro enfoque que utiliza la técnica de métodos de extensión para extender la clase String para agregar compresión y descompresión de cadenas. Puede colocar la clase a continuación en un proyecto existente y luego usarla así:
y
Esto es:
fuente
using
declaraciones para las instancias de MemoryStream. Y para los desarrolladores # F por ahí: se abstengan de utilizar la palabra claveuse
para la instancia compressorStream / decompressorStream, porque tienen que ser eliminados manualmente antes de queToArray()
se vuelve a llamarEsta es una versión actualizada para .NET 4.5 y posterior usando async / await e IEnumerables:
Con esto puedes serializar todo lo que sea
BinaryFormatter
compatible, en lugar de solo cadenas.Editar:
En caso de que necesite cuidarlo
Encoding
, puede usar Convert.ToBase64String (byte []) ...¡Eche un vistazo a esta respuesta si necesita un ejemplo!
fuente
Convert.ToBase64String(byte[])
. Por favor, vea esta respuesta ( stackoverflow.com/a/23908465/3286975 ). ¡Espero eso ayude!Para aquellos que todavía obtienen El número mágico en el encabezado GZip no es correcto. Asegúrate de pasar una transmisión GZip. ERROR y si su cadena se comprimió usando php , deberá hacer algo como:
fuente