将C#对象保存到文件中

12 浏览
0 Comments

将C#对象保存到文件中

该问题很难分辨出要求什么。该问题含糊不清、不完整、过于广泛或抽象,因此不能以其当前的形式合理地回答。如果需要澄清此问题以便重新打开它,请访问帮助中心

我要实现一个新的会员申请,但不使用数据库。我计划创建一个类来定义每个成员,使用字段定义名称、部门等。我希望将这些成员的列表保存到一个文件(不是纯文本文件)中。那么我的问题是如何将一个类对象保存到文件中?

先行致谢 🙂

admin 更改状态以发布 2023年5月24日
0
0 Comments

听起来你想要使用BinaryFormatter。它可以将数据保存在一个不可读的二进制文件中。它的一个主要优点是与XmlSerialization(例如)相比,你的属性不需要是公共的。

然而,我个人会建议你不要这样做。我自己也曾走过这条路,虽然在短期内容易,但在长期内会带来很多麻烦。
你将面临大量的版本问题。每当你想要更新任何对象(比如添加一个新属性),你都需要转换所有的文件。
更糟糕的是,如果你想在同一个应用程序中进行这个操作,你必须同时拥有两个定义。这会导致出现荒谬的类定义,比如:

// my original object
class SavedObject
{
    public string Data{get;set}
}
// needed to add a field for last edit
class SavedObject2
{
    public DateTime LastEdit{get;set;}
    public SavedObject2(SavedObject so){}
}
// need a small restructure so we can now have multiple datas
// 'data' is now obsolete
class SavedObject3
{
    public List DataList{get;set;}
    public SavedObject3(SavedObject2 so){}
}

将序列化作为持久化的一种方式只适用于两种情况。一种是你知道数据定义永远不会改变(非常罕见),另一种是你只是以一种原始的方式保存数据(例如仅仅是一组字符串,然后代码将其转换为类)。

我认为你应该认真考虑使用数据库。如果你不喜欢大多数生产数据库所伴随的管理任务,那么考虑使用Sqlite吧,它小巧、便携且非常易于嵌入应用程序中。

0
0 Comments

我建议使用JSON或XML序列化,然后使用某种算法加密内容。我不会选择二进制序列化,因为当您需要更改程序集版本时,它不太友好。我正在使用以下代码与Newtonsoft.Json(您可以在NuGet上获取它)一起实现此目标:

using System.IO;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
class SecureJsonSerializer
    where T : class
{
    private readonly string filePath;
    private readonly ICryptoTransform encryptor;
    private readonly ICryptoTransform decryptor;
    private const string Password = "some password";
    private static readonly byte[] passwordBytes = Encoding.ASCII.GetBytes(Password);
    public SecureJsonSerializer(string filePath)
    {
        this.filePath = filePath;
        var rmCrypto = GetAlgorithm();
        this.encryptor = rmCrypto.CreateEncryptor();
        this.decryptor = rmCrypto.CreateDecryptor();
    }
    private static RijndaelManaged GetAlgorithm()
    {
        var algorithm = new RijndaelManaged();
        int bytesForKey = algorithm.KeySize / 8;
        int bytesForIV = algorithm.BlockSize / 8;
        algorithm.Key = key.GetBytes(bytesForKey);
        algorithm.IV = key.GetBytes(bytesForIV);
        return algorithm;
    }
    public void Save(T obj)
    {
        using (var writer = new StreamWriter(new CryptoStream(File.Create(this.filePath), this.encryptor, CryptoStreamMode.Write)))
        {
            writer.Write(JsonConvert.SerializeObject(obj));
        }
    }
    public T Load()
    {
        using (var reader = new StreamReader(new CryptoStream(File.OpenRead(this.filePath), this.decryptor, CryptoStreamMode.Read)))
        {
            return JsonConvert.DeserializeObject(reader.ReadToEnd());
        }
    }
}

0