C# serialize big collection via NewtonSoft.Json

System.OutOfMemoryException
  HResult=0x8007000E
  Message=Exception of type 'System.OutOfMemoryException' was thrown.
  Source=mscorlib
  StackTrace:
   at System.Text.StringBuilder.ToString()
   at System.IO.StringWriter.ToString()
   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting)
   at ConsoleApp3.Program.TestBigDataSerialize() in D:\C\ConsoleApp3\ConsoleApp3\Program.cs:line 63
   at ConsoleApp3.Program.Main(String[] args) in D:\C\ConsoleApp3\ConsoleApp3\Program.cs:line 29

 

 

The solution is extend stream

public static class BigDataSerializeStream
{
    public static void WriteJsonToStream<T>(this Stream stream,IEnumerable<T> items)
    {
        using(var streamWriter=new StreamWriter(stream))
        {
            using(var jsonWriter=new JsonTextWriter(streamWriter))
            {  
                var serializer = new JsonSerializer();
                serializer.Formatting = Formatting.Indented;
                serializer.Serialize(streamWriter, items);
            }
        }
    }
}


static void SerializeBigDataViaStream()
{
    BooksList = new List<Book>();
    for (int i = 0; i < 5000000; i++)
    {
        BooksList.Add(new Book()
        {
            Id = i + 1,
            ISBN = $"ISBN_{Guid.NewGuid().ToString("N")}",
            Name = $"Name_{i + 1}",
            Title = $"Title_{i + 1}",
            Topic = $"Topic_{i + 1}"
        });
    }

    string jsonFile = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString("N")}.json";
    using(FileStream fs=File.Create(jsonFile))
    {
        fs.WriteJsonToStream<Book> (BooksList);
        MessageBox.Show($"Serialized {BooksList.Count} items!");
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text; 
using Newtonsoft.Json;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Threading;

namespace ConsoleApp3
{
    internal class Program
    {
        static void Main(string[] args)
        {
            AlarmDelEvent += Program_AlarmDelEvent;
            Thread td = new Thread(() =>
            {
                System.Timers.Timer tmr = new System.Timers.Timer();
                tmr.Interval = 1000;
                tmr.Elapsed += Tmr_Elapsed;
                tmr.Start();
            });
            td.Start();
            //BigDataSerializeRegular();
            SerializeBigDataViaStream();
            Console.ReadLine();
        }

        private static void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var procMem = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
            Console.WriteLine(procMem.ToString());
            if (procMem > 4000000000)
            {
                AlarmDelEvent?.Invoke(procMem);
            }
        }

        public static List<Book> BooksList { get; set; }

        delegate void AlarmDel(double d);
        static event AlarmDel AlarmDelEvent;
        static void BigDataSerializeRegular()
        { 
            BooksList = new List<Book>();
            for (int i = 0; i < 5000000; i++)
            {
                BooksList.Add(new Book()
                {
                    Id = i + 1,
                    ISBN = $"ISBN_{Guid.NewGuid().ToString("N")}",
                    Name = $"Name_{i + 1}",
                    Title = $"Title_{i + 1}",
                    Topic = $"Topic_{i + 1}"
                });
            }

            string jsonStr = JsonConvert.SerializeObject(BooksList, Newtonsoft.Json.Formatting.Indented);
            string jsonFile = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString("N")}.json";
            using (StreamWriter writer = new StreamWriter(jsonFile, true, Encoding.UTF8))
            {
                writer.WriteLine(jsonStr);
                MessageBox.Show($"Saved {BooksList.Count()} in {jsonFile}");
            }
        }

        static void SerializeBigDataViaStream()
        {
            BooksList = new List<Book>();
            for (int i = 0; i < 15000000; i++)
            {
                BooksList.Add(new Book()
                {
                    Id = i + 1,
                    ISBN = $"ISBN_{Guid.NewGuid().ToString("N")}",
                    Name = $"Name_{i + 1}",
                    Title = $"Title_{i + 1}",
                    Topic = $"Topic_{i + 1}"
                });
            }

            string jsonFile = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString("N")}.json";
            using(FileStream fs=File.Create(jsonFile))
            {
                fs.WriteJsonToStream<Book> (BooksList);
                MessageBox.Show($"Serialized {BooksList.Count} items!");
            }
        }

        private static void Program_AlarmDelEvent(double d)
        {
            MessageBox.Show($"Over memory:{d}\n");
        }
    }

    public class Book
    {
        public int Id { get; set; }
        public string ISBN { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
        public string Topic { get; set; }

    }

    public static class BigDataSerializeStream
    {
        public static void WriteJsonToStream<T>(this Stream stream,IEnumerable<T> items)
        {
            using(var streamWriter=new StreamWriter(stream))
            {
                using(var jsonWriter=new JsonTextWriter(streamWriter))
                {  
                    var serializer = new JsonSerializer();
                    serializer.Formatting = Formatting.Indented;
                    serializer.Serialize(streamWriter, items);
                }
            }
        }
    }
       
}

 

posted @ 2024-10-31 23:22  FredGrit  阅读(1)  评论(0编辑  收藏  举报