データベースを使用せずに新しいメンバー アプリケーションを実装する予定です。名前、部門などを定義するフィールドを使用して、各メンバーを定義するクラスを作成する予定です。これらのメンバーのリストをファイルに保存したいと考えています (プレーンテキストではありません)。だから私の質問は、クラスオブジェクトをファイルに保存する方法です?
前もって感謝します :)
データベースを使用せずに新しいメンバー アプリケーションを実装する予定です。名前、部門などを定義するフィールドを使用して、各メンバーを定義するクラスを作成する予定です。これらのメンバーのリストをファイルに保存したいと考えています (プレーンテキストではありません)。だから私の質問は、クラスオブジェクトをファイルに保存する方法です?
前もって感謝します :)
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());
}
}
}
BinaryFormatterが必要なようです。これにより、読み取り不可能なバイナリ ファイルに保存されます。XmlSerialization (たとえば) に対する主な利点の 1 つは、プロパティを公開する必要がないことです。
ただし、個人的には、この考えを思いとどまらせたいと思います。私自身もこの道を歩んできましたが、短期的には簡単ですが、長期的には多くの苦痛が伴います。
バージョン管理には大きな問題があります。オブジェクトを更新する (たとえば、新しいプロパティを追加する) 場合は常に、すべてのファイルを変換する必要があります。
さらに悪いことに、これを同じアプリケーション内で行う場合は、両方の定義を同時に使用できるようにする必要があります。これは、次のような不条理なクラス定義につながります。
// 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){}
}
永続化の手段としてのシリアル化は、2 つのシナリオでのみ有効です。1 つは、データの定義が決して変更されないことがわかっている場合 (信じられないほどまれです)、および 2 つは、単純な方法でデータを保存する場合です (たとえば、コードがクラスに変換される文字列のコレクションのみ)。
データベースの使用を真剣に検討します。ほとんどの実稼働データベースに伴う管理作業が嫌いな場合は、Sqlite の使用を検討してください。Sqlite は小さく、移植可能で、アプリケーション内に組み込むのが非常に簡単です。
まず、このツールを使用してクラスを json にシリアル化できます: Json Net
次に、好みから暗号化ツールを見つけます。たくさんあります。例を次に示します。64 にエンコードします。
その後、ファイルを保存できます。
System.File.WriteAllText(@"C:\file.dat","encripted string");