J'ai passé 5 heures à obtenir une erreur de fin de flux et j'ai perdu des données (fonctionnalité non évidente dans GzipStream : vous devez utiliser le flux sous-jacent uniquement après avoir vidé GzipStream).
Exemple complet de code fonctionnel :
using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string large = LargeJsonContent.GetBigObject();
string base64;
using (var readStream = new MemoryStream())
using (var writeStream = new MemoryStream())
{
using (GZipStream compressor = new GZipStream(writeStream, CompressionMode.Compress, true)) //pay attention to leaveOpen = true
{
var formatter = new BinaryFormatter();
formatter.Serialize(readStream, large);
Console.WriteLine($"After binary serialization of JsonString: {readStream.Length} bytes");
readStream.Position = 0;
readStream.CopyTo(compressor);
}
Console.WriteLine($"Compressed stream size: {writeStream.Length} bytes");
writeStream.Position = 0;
byte[] writeBytes = writeStream.ToArray();
base64 = Convert.ToBase64String(writeBytes);
}
////
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, base64);
Console.WriteLine($"Size of base64: {stream.Length} bytes");
}
Console.WriteLine("---------------------");
////
string large2;
var bytes = Convert.FromBase64String(base64);
using (var readStream = new MemoryStream())
{
readStream.Write(bytes, 0, bytes.Length);
readStream.Position = 0;
Console.WriteLine($"Compressed stream size: {readStream.Length} bytes");
using (var writeStream = new MemoryStream())
{
using (GZipStream decompressor = new GZipStream(readStream, CompressionMode.Decompress, true)) //pay attention to leaveOpen = true
{
decompressor.CopyTo(writeStream);
writeStream.Position = 0;
}
var formatter = new BinaryFormatter();
large2 = (string)formatter.Deserialize(writeStream);
}
}
Console.WriteLine(large == large2);
Console.WriteLine($"large:{large.Length} | large2:{large2.Length}");
}
}
}
0 votes
En plus des problèmes de position du flux signalés ci-dessous, une autre raison pour laquelle cela peut se produire est que votre application se termine avant que le fichier grand site est écrit sur le disque (si vous sérialisez une grande quantité de données dans un flux de fichiers). Pour résoudre ce problème, vous devez implémenter une attente bloquante jusqu'à ce que le fichier soit entièrement écrit, comme dans ce post : stackoverflow.com/questions/10982104/
1 votes
Pour moi, la suppression du fichier de données sauvegardées de " C:\Users\ <Nom d'utilisateur> \AppData\LocalLow\ "Le problème était que j'avais changé de modèle de données après avoir enregistré le fichier, ce qui rendait le modèle des données existantes dans le fichier différent et provoquait des erreurs lors de la désérialisation. J'espère que cela vous aidera.