【发布时间】:2017-06-09 21:47:52
【问题描述】:
我使用以下方法在序列化后将应用程序数据保存到文件中,并在反序列化(en/decrypted)后从该文件中加载数据。
private void SaveClassToFile(string fileAddress, string password, object classToSave)
{
const int ivSaltLength = 16;
byte[] salt = new byte[ivSaltLength];
byte[] iv = new byte[ivSaltLength];
byte[] codedClass = new byte[0];
iv = CreateIV();
salt = CreateSalt();
using (var memoryStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, classToSave);
codedClass = new byte[Convert.ToInt32(memoryStream.Length)];
memoryStream.Seek(0, SeekOrigin.Begin);
if (memoryStream.Read(codedClass, 0, Convert.ToInt32(memoryStream.Length)) != memoryStream.Length)
{throw new Exception("failed to read from memory stream"); }
}
using (SpecialCoderDecoder specialCoder = new SpecialCoderDecoder(SpecialCoderDecoder.Type.Coder, password, salt, iv))
{ specialCoder.Code(codedClass); }
using (FileStream streamWriter = new FileStream(fileAddress, FileMode.CreateNew))
using (BinaryWriter binaryWriter = new BinaryWriter(streamWriter))
{
binaryWriter.Write(salt);
binaryWriter.Write(iv);
binaryWriter.Write(codedClass);
}
}
private object LoadClassFromFile(string fileAddress, string password)
{
const int ivSaltLength = 16;
byte[] salt = new byte[ivSaltLength];
byte[] iv = new byte[ivSaltLength];
byte[] codedClass = new byte[0];
int codedClassLengthToRaed = 0;
FileInfo fileInfo;
object result = null;
fileInfo = new FileInfo(fileAddress);
using (FileStream streamWriter = new FileStream(fileAddress, FileMode.Open))
using (BinaryReader binaryreader = new BinaryReader(streamWriter))
{
salt = binaryreader.ReadBytes(ivSaltLength);
iv = binaryreader.ReadBytes(ivSaltLength);
codedClassLengthToRaed = Convert.ToInt32(fileInfo.Length) - (2 * ivSaltLength);
codedClass = binaryreader.ReadBytes(codedClassLengthToRaed);
}
using (SpecialCoderDecoder specialDecoder = new SpecialCoderDecoder(SpecialCoderDecoder.Type.Decoder, password, salt, iv))
{ specialDecoder.Decode(codedClass); }
using (MemoryStream memoryStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
memoryStream.Write(codedClass, 0, codedClass.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
result = (object)binaryFormatter.Deserialize(memoryStream);
}
return result;
}
如果应用程序中没有数据,我会添加大约 100MB 的数据(基于任务管理器)并保存。加载数据后,任务管理器显示应用程序数据约为 200-400 MB!
为了将应用程序类封装到一个类中以使用此方法,我使用如下类:
public class BigClass
{
public ClassA classA;
public ClassB classB;
public BigClass(ClassA a, ClassB b)
{
classA = a;
classB = b;
}
}
ClassA 和 ClassB(应该保存/加载的类)中的每一个都像:
public class ClassA
{
List<ClassASub> list = new List<ClassASub>();
//some variables...
//some methodes
private class ClassASub
{
int intValue;
long longValue;
string stringValue;
Image image;
//some simple methodes....
}
}
我不谈论序列化/反序列化过程中已用 RAM 的大小。之后我会谈到已使用的 RAM,那时应该只存在应用程序数据。
【问题讨论】:
-
我推荐 Raymond Chen 的这篇博文:Everybody thinks about garbage collection the wrong way
-
我在列表中看到你的 A 类中的一个图像属性,一旦你完成了你的对象 :-)
标签: c# memory serialization