I using following methods to save application data into a file after serialization and load data from this file after deserialization (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;
}
If there be no data in application and I add about 100MB data to it (base on task manager) and save it. After loading data, task manager shows that application data is about 200-400 MB!
For encapsulating application class to one class for use this methods I use a class like:
public class BigClass
{
public ClassA classA;
public ClassB classB;
public BigClass(ClassA a, ClassB b)
{
classA = a;
classB = b;
}
}
That each one of ClassA
and ClassB
(classes that should saves/loads) are like:
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....
}
}
I do not talk about size of used RAM in serialization/deserialization progress. I speak about used RAM after that, when only application data should exists.