using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Island.StandardLib.Storage
{
public static class DataStorageManager
{
static readonly byte[] METAINF = new byte[64] { 33, 88, 67, 78, 66, 33, 32, 80, 104, 121, 83, 105, 109, 32, 83, 116, 111, 114, 97, 103, 101, 32, 70, 105, 108, 101, 32, 68, 79, 32, 78, 79, 84, 32, 69, 68, 73, 84, 32, 84, 72, 73, 83, 32, 70, 73, 76, 69, 32, 85, 83, 69, 32, 84, 69, 88, 84, 32, 69, 68, 73, 84, 79, 82 };
///
/// 按照指定可序列化类型序列化此内存
///
/// 可序列化类型
public static T ReadData(this byte[] bytes) where T : IStorable, new()
{
T instance = new T();
DataStorage ds = new DataStorage(bytes);
instance.ReadFromData(ds);
return instance;
}
public static byte[] GetBytes(this IStorable data)
{
DataStorage ds = new DataStorage();
data.WriteToData(ds);
return ds.Bytes;
}
///
/// 将可序列化类型序列化并存入文件
///
/// 可序列化类型
/// 文件路径
public static void WriteFile(IStorable data, string writeTo)
{
DataStorage ds = new DataStorage();
data.WriteToData(ds);
if (File.Exists(writeTo)) File.Delete(writeTo);
FileStream writer = new FileStream(writeTo, FileMode.Create, FileAccess.Write);
writer.Write(ds.Bytes, 0, ds.Size);
writer.Flush();
writer.Close();
}
public static void WriteFileWithMd(IStorable data, IStorable metadata, string writeTo)
{
byte[] buff_md = metadata.GetBytes(), buff_dat = data.GetBytes();
int pmetadata = METAINF.Length, pbody = pmetadata + buff_md.Length;
FileStream writer = new FileStream(writeTo, FileMode.Create, FileAccess.Write);
writer.Write(BitConverter.GetBytes(pmetadata + 8), 0, 4);
writer.Write(BitConverter.GetBytes(pbody + 8), 0, 4);
writer.Write(METAINF, 0, METAINF.Length);
writer.Flush();
writer.Write(buff_md, 0, buff_md.Length);
writer.Flush();
writer.Write(buff_dat, 0, buff_dat.Length);
writer.Flush();
writer.Close();
}
public static string WriteToString(IStorable data) => Convert.ToBase64String(data.GetBytes());
public static T ReadFromString(string str) where T : IStorable, new() => Convert.FromBase64String(str).ReadData();
public static string WriteToString(IStorable data, string keypass32) => Convert.ToBase64String(AESEncrypt(data.GetBytes(), keypass32));
public static T ReadFromString(string str, string keypass32) where T : IStorable, new() => AESDecrypt(Convert.FromBase64String(str), keypass32).ReadData();
static byte[] AESEncrypt(byte[] plainBytes, string Key)
{
MemoryStream mStream = new MemoryStream();
RijndaelManaged aes = new RijndaelManaged();
byte[] bKey = new byte[32];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 128;
aes.Key = bKey;
CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
try
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
return mStream.ToArray();
}
finally
{
cryptoStream.Close();
mStream.Close();
aes.Clear();
}
}
static byte[] AESDecrypt(byte[] encryptedBytes, string Key)
{
byte[] bKey = new byte[32];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
MemoryStream mStream = new MemoryStream(encryptedBytes);
RijndaelManaged aes = new RijndaelManaged();
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 128;
aes.Key = bKey;
CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
try
{
byte[] tmp = new byte[encryptedBytes.Length + 32];
int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);
byte[] ret = new byte[len];
Array.Copy(tmp, 0, ret, 0, len);
return ret;
}
finally
{
cryptoStream.Close();
mStream.Close();
aes.Clear();
}
}
public static MdType ReadFileWithMd_Md(string readFrom) where MdType : IStorable, new()
{
FileStream reader = new FileStream(readFrom, FileMode.Open, FileAccess.Read);
byte[] buff_md_p = new byte[4], buff_dat_p = new byte[4];
reader.Read(buff_md_p, 0, 4);
reader.Read(buff_dat_p, 0, 4);
int md_p = BitConverter.ToInt32(buff_md_p, 0), dat_p = BitConverter.ToInt32(buff_dat_p, 0);
byte[] buff_md = new byte[dat_p - md_p];
reader.Position = md_p;
reader.Read(buff_md, 0, buff_md.Length);
reader.Close();
return buff_md.ReadData();
}
public static DataType ReadFileWithMd_Data(string readFrom) where DataType : IStorable, new()
{
FileStream reader = new FileStream(readFrom, FileMode.Open, FileAccess.Read);
byte[] buff_dat_p = new byte[4];
reader.Position = 4;
reader.Read(buff_dat_p, 0, 4);
int dat_p = BitConverter.ToInt32(buff_dat_p, 0);
reader.Position = dat_p;
byte[] buff_data = new byte[reader.Length - dat_p];
reader.Read(buff_data, 0, buff_data.Length);
reader.Close();
return buff_data.ReadData();
}
///
/// 将此可序列化类型序列化并存入文件
///
/// 文件路径
public static void WriteToFile(this IStorable data, string writeTo)
{
WriteFile(data, writeTo);
}
///
/// 从文件中读取并创建可序列化类型实例
///
/// 文件路径
public static T ReadFile(string readFrom) where T : IStorable, new()
{
if (!File.Exists(readFrom)) throw new FileNotFoundException();
FileStream reader = new FileStream(readFrom, FileMode.Open, FileAccess.Read);
byte[] data = new byte[reader.Length];
reader.Read(data, 0, data.Length);
reader.Close();
DataStorage ds = new DataStorage(data);
T instance = new T();
instance.ReadFromData(ds);
return instance;
}
}
}