2015-10-05 4 views
5

मेरा एप्लिकेशन Json.Net का उपयोग करके किसी ऑब्जेक्ट को क्रमबद्ध करता है, परिणामी JSON को संपीड़ित करता है, फिर इसे फ़ाइल में सहेजता है। इसके अतिरिक्त एप्लिकेशन इन फ़ाइलों में से किसी एक से ऑब्जेक्ट लोड कर सकता है। इन वस्तुओं के आकार में एमबी के दसियों हो सकता है और मैं स्मृति के उपयोग को लेकर चिंतित हूं, जिस तरीके को मौजूदा कोड बड़े तार और बाइट सरणियों बनाता है: -क्या मैं धाराओं का उपयोग कर फ़ाइल को डीकंप्रेस और deserialize कर सकते हैं?

public void Save(MyClass myObject, string filename) 
{ 
    var json = JsonConvert.SerializeObject(myObject); 
    var bytes = Compress(json); 
    File.WriteAllBytes(filename, bytes); 
} 

public MyClass Load(string filename) 
{  
    var bytes = File.ReadAllBytes(filename); 
    var json = Decompress(bytes); 
    var myObject = JsonConvert.DeserializeObject<MyClass>(json); 
} 

private static byte[] Compress(string s) 
{ 
    var bytes = Encoding.Unicode.GetBytes(s); 

    using (var ms = new MemoryStream()) 
    { 
     using (var gs = new GZipStream(ms, CompressionMode.Compress)) 
     { 
      gs.Write(bytes, 0, bytes.Length); 
      gs.Close(); 
      return ms.ToArray(); 
     } 
    } 
} 

private static string Decompress(byte[] bytes) 
{ 
    using (var msi = new MemoryStream(bytes)) 
    { 
     using (var mso = new MemoryStream()) 
     { 
      using (var gs = new GZipStream(msi, CompressionMode.Decompress)) 
      { 
       gs.CopyTo(mso); 
       return Encoding.Unicode.GetString(mso.ToArray()); 
      } 
     } 
    } 
} 

मैं सोच रहा था अगर सहेजें/लोड तरीकों सकता है धाराओं के साथ प्रतिस्थापित किया जा सकता है? मुझे Json.Net के साथ स्ट्रीम का उपयोग करने के उदाहरण मिल गए हैं, लेकिन अतिरिक्त संपीड़न सामग्री में फिट होने के तरीके के बारे में मेरे सिर को पाने के लिए संघर्ष कर रहा हूं।

+1

यह आपको http://benfoster.io/blog/aspnet-web-api-compression –

+0

@Roy मैं गया है OOM अपवाद हाल ही में देख रहे दिलचस्प साबित हो सकता है और इस कोड को तार्किक अपराधी लग रहा था। मैं वीएस मेमोरी प्रोफाइलर की अपनी रिपोर्ट तैयार करने के लिए इंतजार कर रहा हूं (इतनी धीमी ...), इसलिए मुझे जल्द ही एक बेहतर विचार होगा, लेकिन सोचा कि मैं इस कोड को दोबारा जोड़ने की कोशिश करता हूं, जबकि मैं अपने अंगूठे को झुका रहा हूं! –

+0

@AndrewStephens Ah goodo। शायद प्रश्न में अपने ओओएम का जिक्र करें। सौभाग्य! – MickyD

उत्तर

5

JsonSerializer एक JsonTextReader से और एक StreamWriter को क्रमानुसार करने के तरीकों, जो दोनों के धारा के किसी भी प्रकार, एक GZipStream सहित की चोटी पर बनाया जा सकता है है। उन्हें का उपयोग करना, आप निम्नलिखित विस्तार तरीकों बना सकते हैं:

public static class JsonExtensions 
{ 
    public static void SerializeToFileCompressed(object value, string path, JsonSerializerSettings settings = null) 
    { 
     using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) 
      SerializeCompressed(value, fs, settings); 
    } 

    public static void SerializeCompressed(object value, Stream stream, JsonSerializerSettings settings = null) 
    { 
     using (var compressor = new GZipStream(stream, CompressionMode.Compress)) 
     using (var writer = new StreamWriter(compressor)) 
     { 
      var serializer = JsonSerializer.CreateDefault(settings); 
      serializer.Serialize(writer, value); 
     } 
    } 

    public static T DeserializeFromFileCompressed<T>(string path, JsonSerializerSettings settings = null) 
    { 
     using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) 
      return DeserializeCompressed<T>(fs, settings); 
    } 

    public static T DeserializeCompressed<T>(Stream stream, JsonSerializerSettings settings = null) 
    { 
     using (var compressor = new GZipStream(stream, CompressionMode.Decompress)) 
     using (var reader = new StreamReader(compressor)) 
     using (var jsonReader = new JsonTextReader(reader)) 
     { 
      var serializer = JsonSerializer.CreateDefault(settings); 
      return serializer.Deserialize<T>(jsonReader); 
     } 
    } 
} 

Performance Tips: Optimize Memory Usage देखें Json.NET दस्तावेज में।

+1

ग्रेट सामान। मैं मिश्रित हो रहा था कि कैसे विभिन्न पाठकों और धाराओं को घोंसला किया जाना चाहिए। इस कोड का उपयोग करने के लिए रिफैक्टरिंग के परिणामस्वरूप स्मृति उपयोग में काफी सुधार हुआ है। –

1

उन लोगों के लिए जो यूवीपी ऐप्स में @ डीबीसी से एक्सटेंशन का उपयोग कैसे करें, इसके लिए मैंने कोड को संशोधित किया - जहां स्टोरेजफाइल एक फ़ाइल है जिसे आपके पास लिखने के लिए उपयोग है।

public static async void SerializeToFileCompressedAsync(object value, StorageFile file, JsonSerializerSettings settings = null) 
{ 
    using (var stream = await file.OpenStreamForWriteAsync()) 
     SerializeCompressed(value, stream, settings); 
} 

public static void SerializeCompressed(object value, Stream stream, JsonSerializerSettings settings = null) 
{ 
    using (var compressor = new GZipStream(stream, CompressionMode.Compress)) 
    using (var writer = new StreamWriter(compressor)) 
    { 
     var serializer = JsonSerializer.CreateDefault(settings); 
     serializer.Serialize(writer, value); 
    } 
} 

public static async Task<T> DeserializeFromFileCompressedAsync<T>(StorageFile file, JsonSerializerSettings settings = null) 
{ 
    using (var stream = await file.OpenStreamForReadAsync()) 
     return DeserializeCompressed<T>(stream, settings); 
} 

public static T DeserializeCompressed<T>(Stream stream, JsonSerializerSettings settings = null) 
{ 
    using (var compressor = new GZipStream(stream, CompressionMode.Decompress)) 
    using (var reader = new StreamReader(compressor)) 
    using (var jsonReader = new JsonTextReader(reader)) 
    { 
     var serializer = JsonSerializer.CreateDefault(settings); 
     return serializer.Deserialize<T>(jsonReader); 
    } 
} 
संबंधित मुद्दे