C# 对象二进制序列化

C# 对象二进制序列化,c#,string,serialization,binaryformatter,C#,String,Serialization,Binaryformatter,我想对一个对象进行二进制序列化,并将结果保存到数据库中 Person person = new Person(); person.Name = "something"; MemoryStream memorystream = new MemoryStream(); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(memorystream, person); 如何将memorystream转换为字符串类型以保存在数据库中,然后才

我想对一个对象进行二进制序列化,并将结果保存到数据库中

Person person = new Person();
person.Name = "something";

MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);
如何将memorystream转换为字符串类型以保存在数据库中,然后才能反序列化对象?

您真正需要的是一种安全的方法,将任意二进制数据表示为文本,然后再将其转换回。它存储序列化对象的事实与此无关

答案几乎是使用Base 64(例如and)。不要使用
Encoding.UTF8.GetString
或任何类似的方法-您的二进制数据不是经过编码的文本数据,不应被视为文本数据


但是,您的数据库是否没有二进制数据的数据类型?检查BLOB、图像和二进制类型…

我使用了类似的东西

MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, Person);
memoryStream.Flush();
memoryStream.Position = 0;
string value = Convert.ToBase64String(memoryStream.ToArray());

基本上,将数据作为字符串保存到数据库中,有
blob
字段可用于存储二进制数据


如果确实需要将数据作为字符串,则需要使用base64编码将字节[]转换为字符串,并使用解码从字符串中获取字节[]。

您没有考虑过将memorystream转换为base64十六进制字符串以放入数据库吗

 byte[] mStream = memorystream.ToArray();
 string sConvertdHex = System.Convert.ToBase64String(mStream)
然后可以将内容sConvertdHex转储到数据库。要反序列化它,需要执行相反的操作

 byte[] mData = System.Convert.FromBase64String(...)

然后将mData反序列化回您的对象。

以下是示例。TData必须标记为[Serializable],并且所有字段类型也必须相同

    private static TData DeserializeFromString<TData>(string settings)
    {
        byte[] b = Convert.FromBase64String(settings);
        using (var stream = new MemoryStream(b))
        {
            var formatter = new BinaryFormatter();
            stream.Seek(0, SeekOrigin.Begin);
            return (TData)formatter.Deserialize(stream);
        }
    }

    private static string SerializeToString<TData>(TData settings)
    {
        using (var stream = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(stream, settings);
            stream.Flush();
            stream.Position = 0;
            return Convert.ToBase64String(stream.ToArray());
        }
    }
private static TData反序列化fromstring(字符串设置)
{
字节[]b=转换.FromBase64String(设置);
使用(var流=新内存流(b))
{
var formatter=新的二进制格式化程序();
stream.Seek(0,SeekOrigin.Begin);
返回(TData)格式化程序。反序列化(流);
}
}
专用静态字符串序列化字符串(TData设置)
{
使用(var stream=new MemoryStream())
{
var formatter=新的二进制格式化程序();
序列化(流、设置);
stream.Flush();
流位置=0;
返回Convert.ToBase64String(stream.ToArray());
}
}

在调用ToArray之前,不需要倒带MemoryStream—它返回整个流的数据,而不管当前位置如何。同样,Flush在MemoryStream上也不做任何事情,尽管它通常对流是一个好主意。在
MemoryStream
字节的字符串周围应该有一个
使用
,需要一些编码。@loneshark99:我完全不理解你的评论。如果这是任意的二进制数据,而不是编码的文本,那么使用
编码将完全是错误的方法,但是我想知道为什么编码不是正确的方法,而ToBase64String是。@loneshark99:因为
编码
是为固有的文本数据设计的-它将文本转换为二进制数据,而base64和hex的设计目的是在不丢失信息的情况下,将固有的二进制任意数据表示为文本!。我总是对编码感到困惑。非常感谢。
//-------write to database-------------------------
Person person = new Person();
person.name = "Firstnm  Lastnm";
MemoryStream memorystream = new MemoryStream(); 
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);
byte[] yourBytesToDb = memorystream.ToArray();
//here you write yourBytesToDb to database


//----------read from database---------------------
//here you read from database binary data into yourBytesFromDb
MemoryStream memorystreamd = new MemoryStream(yourBytesFromDb);
BinaryFormatter bfd = new BinaryFormatter();
Person deserializedperson = bfd.Deserialize(memorystreamd) as Person;