C# jsonconvert and binaryformater both in serialize and deserialize
public DelCmd ExportAllCmd { get; set; } public DelCmd ExportAllBinaryFormatterCmd { get; set; } public DelCmd DeserializeJsonFileCmd { get; set; } public DelCmd DeserializeBinFileCmd { get; set; } private void InitCmds() { ExportAllCmd = new DelCmd(ExportAllCmdExecuted); ExportAllBinaryFormatterCmd = new DelCmd(ExportAllBinaryFormatterCmdExecuted); DeserializeJsonFileCmd = new DelCmd(DeserializeJsonFileCmdExecuted); DeserializeBinFileCmd = new DelCmd(DeserializeBinFileCmdExecuted); } private void DeserializeBinFileCmdExecuted(object obj) { string binFile = "BinFormatter202409141240168002_378cf4d8-63ed-451d-9a42-2d240d8f386f.bin"; if (File.Exists(binFile)) { try { StringBuilder costBuilder = new StringBuilder(); Stopwatch watch = new Stopwatch(); BinaryFormatter binFormatter = new BinaryFormatter(); using (FileStream fs = new FileStream(binFile, FileMode.Open, FileAccess.Read)) { watch.Start(); var booksList = (List<Book>)binFormatter.Deserialize(fs); if (booksList != null && booksList.Any()) { watch.Stop(); costBuilder.AppendLine($"BinaryFormatter Deserialize cost:{watch.ElapsedMilliseconds},count:{booksList.Count}"); string costMsg = costBuilder.ToString(); File.AppendAllText("cost.txt", costMsg + "\n"); MessageBox.Show(costMsg, "Time cost", MessageBoxButton.OK); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } private void DeserializeJsonFileCmdExecuted(object obj) { string jsonFile = "JsonConvert202409141240130088_ae3c2d74-b0b8-405b-add4-6aafd132b2b2.json"; StringBuilder costBuilder = new StringBuilder(); if(File.Exists(jsonFile)) { try { Stopwatch watch = new Stopwatch(); string jsonStr = File.ReadAllText(jsonFile); watch.Start(); var booksList = JsonConvert.DeserializeObject<List<Book>>(jsonStr); watch.Stop(); if (booksList != null && booksList.Any()) { costBuilder.AppendLine($"JsonConvert Deserialize cost:{watch.ElapsedMilliseconds},count:{booksList.Count}"); string costMsg = costBuilder.ToString(); File.AppendAllText("cost.txt", costMsg + "\n"); MessageBox.Show(costMsg, "Time cost", MessageBoxButton.OK); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } private void ExportAllBinaryFormatterCmdExecuted(object obj) { var dg = obj as DataGrid; if (dg != null) { var items = dg.ItemsSource.Cast<Book>()?.ToList(); if (items != null && items.Any()) { string allJsonFile = $"BinFormatter{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}.bin"; using (FileStream fs = new FileStream(allJsonFile, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { BinaryFormatter binFormatter = new BinaryFormatter(); binFormatter.Serialize(fs, items); } MessageBox.Show($"Exported at:\n{allJsonFile}","BinFormatter Export successfully!", MessageBoxButton.OK); } } } private void ExportAllCmdExecuted(object obj) { var dg = obj as DataGrid; if (dg != null) { var items = dg.ItemsSource.Cast<Book>()?.ToList(); if (items != null && items.Any()) { string allJsonFile = $"JsonConvert{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}.json"; string jsonStr = JsonConvert.SerializeObject(items); File.AppendAllText(allJsonFile, jsonStr); MessageBox.Show($"Exported at:\n{allJsonFile}", "JsonConvert Export successfully!", MessageBoxButton.OK); } } } private void ExportSelectedCmdExecuted(object obj) { var dg = obj as DataGrid; if (dg != null) { var items = dg.SelectedItems.Cast<Book>()?.ToList(); if (items != null && items.Any()) { string jsonStr = JsonConvert.SerializeObject(items, formatting: Formatting.Indented); string selectedFile = $"Selected{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}.json"; File.AppendAllText(selectedFile, jsonStr); MessageBox.Show($"Exported at:\n{selectedFile}", "Export successfully!", MessageBoxButton.OK); } } }
BinaryFormatter's size is smaller than jsonconvert but spend more time.
<Window x:Class="WpfApp365.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp365" mc:Ignorable="d" WindowState="Maximized" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <local:BookVM/> </Window.DataContext> <Grid> <DataGrid x:Name="dg" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsContainerVirtualizable="True" SelectionMode="Extended" AutoGenerateColumns="False" CanUserAddRows="False"> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="Export Selected" Command="{Binding ExportSelectedCmd}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu},Path=PlacementTarget}"/> <MenuItem Header="Export All NewtonJson" Command="{Binding ExportAllCmd}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu},Path=PlacementTarget}"/> <MenuItem Header="Export All BinaryFormatter" Command="{Binding ExportAllBinaryFormatterCmd}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu},Path=PlacementTarget}"/> <MenuItem Header="Deserialize Json File" Command="{Binding DeserializeJsonFileCmd}"/> <MenuItem Header="Deserialize Binary File" Command="{Binding DeserializeBinFileCmd}"/> </ContextMenu> </DataGrid.ContextMenu> <DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding Id}"/> <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> <DataGridTextColumn Header="Title" Binding="{Binding Title}"/> <DataGridTextColumn Header="Topic" Binding="{Binding Topic}"/> <DataGridTemplateColumn Header="Image"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <local:ImageTbk ImgUrl="{Binding DataContext.PicUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}" TbkStr="{Binding DataContext.Name,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window> //cs using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; using Microsoft.SqlServer.Server; using System.Runtime.Serialization.Formatters.Binary; using System.Diagnostics; using System.Text.RegularExpressions; namespace WpfApp365 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } public class BookVM : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if(handler!=null) { handler?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public BookVM() { InitData(); InitCmds(); } private void InitCmds() { ExportSelectedCmd = new DelCmd(ExportSelectedCmdExecuted); ExportAllCmd = new DelCmd(ExportAllCmdExecuted); ExportAllBinaryFormatterCmd = new DelCmd(ExportAllBinaryFormatterCmdExecuted); DeserializeJsonFileCmd = new DelCmd(DeserializeJsonFileCmdExecuted); DeserializeBinFileCmd = new DelCmd(DeserializeBinFileCmdExecuted); } private void DeserializeBinFileCmdExecuted(object obj) { string binFile = "BinFormatter202409141240168002_378cf4d8-63ed-451d-9a42-2d240d8f386f.bin"; if (File.Exists(binFile)) { try { StringBuilder costBuilder = new StringBuilder(); Stopwatch watch = new Stopwatch(); BinaryFormatter binFormatter = new BinaryFormatter(); using (FileStream fs = new FileStream(binFile, FileMode.Open, FileAccess.Read)) { watch.Start(); var booksList = (List<Book>)binFormatter.Deserialize(fs); if (booksList != null && booksList.Any()) { watch.Stop(); costBuilder.AppendLine($"BinaryFormatter Deserialize cost:{watch.ElapsedMilliseconds},count:{booksList.Count}"); string costMsg = costBuilder.ToString(); File.AppendAllText("cost.txt", costMsg + "\n"); MessageBox.Show(costMsg, "Time cost", MessageBoxButton.OK); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } private void DeserializeJsonFileCmdExecuted(object obj) { string jsonFile = "JsonConvert202409141240130088_ae3c2d74-b0b8-405b-add4-6aafd132b2b2.json"; StringBuilder costBuilder = new StringBuilder(); if(File.Exists(jsonFile)) { try { Stopwatch watch = new Stopwatch(); string jsonStr = File.ReadAllText(jsonFile); watch.Start(); var booksList = JsonConvert.DeserializeObject<List<Book>>(jsonStr); watch.Stop(); if (booksList != null && booksList.Any()) { costBuilder.AppendLine($"JsonConvert Deserialize cost:{watch.ElapsedMilliseconds},count:{booksList.Count}"); string costMsg = costBuilder.ToString(); File.AppendAllText("cost.txt", costMsg + "\n"); MessageBox.Show(costMsg, "Time cost", MessageBoxButton.OK); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } private void ExportAllBinaryFormatterCmdExecuted(object obj) { var dg = obj as DataGrid; if (dg != null) { var items = dg.ItemsSource.Cast<Book>()?.ToList(); if (items != null && items.Any()) { string allJsonFile = $"BinFormatter{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}.bin"; using (FileStream fs = new FileStream(allJsonFile, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { BinaryFormatter binFormatter = new BinaryFormatter(); binFormatter.Serialize(fs, items); } MessageBox.Show($"Exported at:\n{allJsonFile}","BinFormatter Export successfully!", MessageBoxButton.OK); } } } private void ExportAllCmdExecuted(object obj) { var dg = obj as DataGrid; if (dg != null) { var items = dg.ItemsSource.Cast<Book>()?.ToList(); if (items != null && items.Any()) { string allJsonFile = $"JsonConvert{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}.json"; string jsonStr = JsonConvert.SerializeObject(items); File.AppendAllText(allJsonFile, jsonStr); MessageBox.Show($"Exported at:\n{allJsonFile}", "JsonConvert Export successfully!", MessageBoxButton.OK); } } } private void ExportSelectedCmdExecuted(object obj) { var dg = obj as DataGrid; if (dg != null) { var items = dg.SelectedItems.Cast<Book>()?.ToList(); if (items != null && items.Any()) { string jsonStr = JsonConvert.SerializeObject(items, formatting: Formatting.Indented); string selectedFile = $"Selected{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}.json"; File.AppendAllText(selectedFile, jsonStr); MessageBox.Show($"Exported at:\n{selectedFile}", "Export successfully!", MessageBoxButton.OK); } } } private void InitData() { var imgsList = System.IO.Directory.GetFiles(@"../../Images"); int imgsCnt = imgsList.Count(); BooksCollection = new ObservableCollection<Book>(); for (int i=0;i<100000;i++) { BooksCollection.Add(new Book() { Id = i + 1, Name = $"Name_{i + 1}", PicUrl = $"{imgsList[i % imgsCnt]}", Title = $"Title_{i + 1}", Topic=$"Topic_{Guid.NewGuid().ToString("N")}" }); } } private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { if(value!=booksCollection) { booksCollection = value; OnPropertyChanged(nameof(BooksCollection)); } } } public DelCmd ExportSelectedCmd { get; set; } public DelCmd ExportAllCmd { get; set; } public DelCmd ExportAllBinaryFormatterCmd { get; set; } public DelCmd DeserializeJsonFileCmd { get; set; } public DelCmd DeserializeBinFileCmd { get; set; } } [Serializable] public class Book { public int Id { get; set; } public string Name { get; set; } public string PicUrl { get; set; } public string Title { get; set; } public string Topic { get; set; } } public class DelCmd : ICommand { public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } private Action<object> execute; private Predicate<object> canExecute; public DelCmd(Action<object> executeValue,Predicate<object> canExecuteValue) { execute= executeValue; canExecute= canExecuteValue; } public DelCmd(Action<object> executeValue):this(executeValue,null) { } public bool CanExecute(object parameter) { if(canExecute==null) { return true; } return canExecute(parameter); } public void Execute(object parameter) { execute(parameter); } } } //usercontrol //xaml <UserControl x:Class="WpfApp365.ImageTbk" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp365" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Image Source="{Binding ImgUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="100" Height="250"/> <TextBlock Text="{Binding TkbStr,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </Grid> </UserControl> //cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp365 { /// <summary> /// Interaction logic for ImageTbk.xaml /// </summary> public partial class ImageTbk : UserControl { public ImageTbk() { InitializeComponent(); this.DataContext = this; } public string ImgUrl { get { return (string)GetValue(ImgUrlProperty); } set { SetValue(ImgUrlProperty, value); } } // Using a DependencyProperty as the backing store for ImgUrl. This enables animation, styling, binding, etc... public static readonly DependencyProperty ImgUrlProperty = DependencyProperty.Register("ImgUrl", typeof(string), typeof(ImageTbk), new PropertyMetadata("")); public string TbkStr { get { return (string)GetValue(TbkStrProperty); } set { SetValue(TbkStrProperty, value); } } // Using a DependencyProperty as the backing store for TbkStr. This enables animation, styling, binding, etc... public static readonly DependencyProperty TbkStrProperty = DependencyProperty.Register("TbkStr", typeof(string), typeof(ImageTbk), new PropertyMetadata("")); } }