【问题标题】:What is the simplest way to do serialization deserialization for boolean variables in C#?在 C# 中对布尔变量进行序列化反序列化的最简单方法是什么?
【发布时间】:2019-07-17 11:30:32
【问题描述】:

当我停止并重新启动程序时,我有一个标志类(以及一个更改标志值的简单按钮)我想查看更改后的布尔变量。我对它进行了搜索,但我有点迷路了。 现在我有一个构造函数,但我不知道如何将它与保存/加载函数一起使用。

最简单的方法是什么?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Xml;
namespace SaveReloadDeneme
{
    [Serializable]
    public partial class Form1 : Form
    {
        bool flag;
        bool flag2;
        public Form1()
        {
            InitializeComponent();
            flag = false;
            flag2 = false;
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            flag = true;
            flag2 = true;
            Console.WriteLine("Flag changed: " + flag);
            Console.WriteLine("Flag2 changed: " + flag2);
        }



        void SaveData()
        {
            // Create a hashtable of values that will eventually be serialized.
            Hashtable addresses = new Hashtable();
            addresses.Add(1, flag);


            // To serialize the hashtable and its key/value pairs,   
            // you must first open a stream for writing.  
            // In this case, use a file stream.
            FileStream fs = new FileStream("DataFile.dat", FileMode.Create);

            // Construct a BinaryFormatter and use it to serialize the data to the stream.
            BinaryFormatter formatter = new BinaryFormatter();
            try
            {
                formatter.Serialize(fs, addresses);
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to serialize. Reason: " + e.Message);
                throw;
            }
            finally
            {
                fs.Close();
            }
        }


        public void LoadData()
        {
            // Declare the hashtable reference.
            Hashtable addresses = null;

            // Open the file containing the data that you want to deserialize.
            FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
            try
            {
                BinaryFormatter formatter = new BinaryFormatter();

                // Deserialize the hashtable from the file and  
                // assign the reference to the local variable.
                addresses = (Hashtable)formatter.Deserialize(fs);
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
                throw;
            }
            finally
            {
                fs.Close();
            }
           }
        private void Button2_Click(object sender, EventArgs e)
        {

        }
}

static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
            Form1 f = new Form1();
            f.SaveData();
            f.LoadData(); 

        }

当我打开 ".dat" 文件时,它是乱码,我认为不包含当前保存的标志值。

【问题讨论】:

  • 我建议使用 JSON。它简单易懂,并且具有相当的人类可读性。
  • @mjwills 好的,我会尝试使用 JSON
  • 看你的代码,可能不是序列化问题,而是对你程序的初始化工作原理的误解。

标签: c# serialization boolean deserialization


【解决方案1】:

序列化和反序列化看起来不错。但在您的Main() 方法中,您首先保存 数据,然后重新加载 保存的(默认)数据。所以你覆盖了保存的数据。
调整您的代码将给出:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);        
        Form1 newForm = new Form1();           
        newForm.LoadData(); 
        Application.Run(newForm);
    }

您还可以在数据更改之前保存数据。 SaveData() 方法在关闭应用程序之前会更好。所以扩展或以前的代码将是:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);  
    Form1 newForm = new Form1();           
    newForm.LoadData(); 
    Application.ApplicationExit += (o, e) => newForm.SaveData();      
    Application.Run(newForm );
}

【讨论】:

  • 谢谢,但是它把结果保存在“.dat”文件中但我看不到它,你知道如何以正确的格式显示,否则我看不到保存的值。
  • 单击按钮,关闭表单并重新启动它。结果如何?您可以在反序列化之后(addresses = (Hashtable)formatter.Deserialize(fs); 之后)放置一个断点,然后将鼠标悬停在adresses 之后查看结果。
  • 您可以序列化为 XML。在thisanwer 中有解释。
【解决方案2】:

正如 mjwils 所说,JSON 可能是一个不错的选择。

Here 是一些例子。

using System;
using System.IO;
using Newtonsoft.Json;

public class Program
{

    public class Movie
    {
        public string Name { get; set; }
        public int Year { get; set; }
    }

    public static void Main()
    {
        Movie movie = new Movie
        {
            Name = "Bad Boys",
            Year = 1995
        };

        // serialize JSON to a string and then write string to a file
        string json =  JsonConvert.SerializeObject(movie);
        Console.WriteLine(json);
        File.WriteAllText("your.path.here", json);

        string json2 = File.ReadAllText("your.path.here");
        Movie movie2 = JsonConvert.DeserializeObject<Movie>(json);
        Console.WriteLine(movie2.Name);
    }
}

【讨论】:

  • 在您的代码中,它不执行反序列化部分。它写入 txt 但是当我关闭并打开程序标志时没有更新。编译器说没有使用 Movie2
  • @Deniz 这是一个如何将序列化对象写入文件的示例,您应该将 Movie 类替换为您的数据(在这种情况下为标志)。
猜你喜欢
  • 2014-05-14
  • 2021-10-24
  • 2010-12-27
  • 2021-01-06
  • 2015-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多