3

我要在不使用数据库的情况下实现一个新的成员应用程序。我打算创建一个类来定义每个成员,其中包含定义名称、部门等的字段。我希望将这些成员的列表保存到文件中(不是纯文本)。所以我的问题是如何将类对象保存到文件中?

提前致谢 :)

4

3 回答 3

7

我建议进行 JSON 或 XML 序列化,然后使用某种算法加密内容。我不会使用二进制序列化,因为当您需要更改程序集版本时它不是很友好。

我将以下代码与 Newtonsoft.Json(您可以在 NuGet 上获得)一起使用来完成此操作:

using System.IO;
using System.Security.Cryptography;
using System.Text;

using Newtonsoft.Json;

class SecureJsonSerializer<T>
    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<T>(reader.ReadToEnd());
        }
    }
}
于 2013-02-24T20:52:50.937 回答
2

听起来你想要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<string> DataList{get;set;}
    public SavedObject3(SavedObject2 so){}
}

序列化作为一种​​持久性手段仅在两种情况下有效。一个您知道数据的定义永远不会改变(非常罕见)和:两个您只是以原始方式保存数据(例如,只是一个字符串集合,然后代码转换为类)。

我会认真考虑使用数据库。如果您不喜欢大多数生产数据库附带的管理琐事,那么请考虑使用 Sqlite,它体积小、可移植且非常容易嵌入到应用程序中。

于 2013-02-24T21:09:07.050 回答
0

那么首先你可以使用这个工具将你的类序列化为 json:Json Net

其次从您的喜好中找到任何加密工具,有很多,这里是示例:编码为64

之后,您可以保存文件:

    System.File.WriteAllText(@"C:\file.dat","encripted string");
于 2013-02-24T20:55:35.723 回答