Je suis novice en .net. Je fais des chaînes de compression et de décompression en C #. Il y a un XML et je convertis en chaîne et après cela je fais de la compression et de la décompression.Il n'y a pas d'erreur de compilation dans mon code sauf lorsque je décompresse mon code et renvoie ma chaîne, il ne renvoie que la moitié du XML.
Ci-dessous mon code, veuillez me corriger là où je me trompe.
Code:
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);
}
}
Ma taille XML est de 63 Ko.
c#
string
.net-2.0
compression
Mohit Kumar
la source
la source
using
.Encoding
le mauvais sens. Vous avez besoin de la base 64 ici, selon la réponse de xanatosRéponses:
Le code pour compresser / décompresser une chaîne
N'oubliez pas que
Zip
renvoie abyte[]
, tandis queUnzip
renvoie astring
. Si vous voulez une chaîne,Zip
vous pouvez l'encoder en Base64 (par exemple en utilisantConvert.ToBase64String(r1)
) (le résultat deZip
est TRÈS binaire! Ce n'est pas quelque chose que vous pouvez imprimer à l'écran ou écrire directement dans un XML)La version suggérée est pour .NET 2.0, pour .NET 4.0 utilisez le
MemoryStream.CopyTo
.IMPORTANT: Le contenu compressé ne peut pas être écrit dans le flux de sortie tant que le ne
GZipStream
sait pas qu'il a toutes les entrées (c'est-à-dire que pour compresser efficacement, il a besoin de toutes les données). Vous devez vous assurer que vousDispose()
le faitesGZipStream
avant d'inspecter le flux de sortie (par exemple,mso.ToArray()
). Ceci est fait avec leusing() { }
bloc ci-dessus. Notez que leGZipStream
est le bloc le plus interne et que le contenu est accessible en dehors de celui-ci. La même chose vaut pour décomprimer:Dispose()
desGZipStream
avant de tenter d'accéder aux données.la source
string s = "X\uD800Y"
. J'ai remarqué que cela fonctionne si nous changeons l'encodage en UTF7 ... mais avec UTF7 sommes-nous sûrs que tous les caractères peuvent être représentés?selon cet extrait, j'utilise ce code et cela fonctionne bien:
la source
Avec l'avènement de .NET 4.0 (et supérieur) avec les méthodes Stream.CopyTo (), j'ai pensé publier une approche mise à jour.
Je pense également que la version ci-dessous est utile comme exemple clair de classe autonome pour compresser des chaînes régulières en chaînes encodées en Base64, et vice versa:
Voici une autre approche utilisant la technique des méthodes d'extension pour étendre la classe String pour ajouter une compression et une décompression de chaîne. Vous pouvez déposer la classe ci-dessous dans un projet existant, puis utiliser ainsi:
et
En être témoin:
la source
using
déclarations pour les instances MemoryStream. Et aux développeurs F # là-bas: évitez d'utiliser le mot-cléuse
pour l'instance compresseurStream / decompressorStream, car ils doivent être supprimés manuellement avant d'ToArray()
être appelésIl s'agit d'une version mise à jour pour .NET 4.5 et plus récent utilisant async / await et IEnumerables:
Avec cela, vous pouvez sérialiser tout ce qui
BinaryFormatter
prend en charge, au lieu uniquement des chaînes.Éditer:
Au cas où vous auriez besoin de vous en occuper
Encoding
, vous pouvez simplement utiliser Convert.ToBase64String (byte []) ...Jetez un œil à cette réponse si vous avez besoin d'un exemple!
la source
Convert.ToBase64String(byte[])
. Veuillez consulter cette réponse ( stackoverflow.com/a/23908465/3286975 ). J'espère que ça aide!Pour ceux qui obtiennent toujours Le nombre magique dans l'en-tête GZip n'est pas correct. Assurez-vous que vous passez dans un flux GZip. ERREUR et si votre chaîne a été compressée avec php, vous devrez faire quelque chose comme:
la source