我在c#
中有一本字典private Dictionary<int, UserSessionInfo> userSessionLookupTable = new Dictionary<int, UserSessionInfo>();
现在我已经创建了一个字典对象
this.userSessionLookupTable.Add(userSessionInfoLogin.SessionId, userSessionInfoLogin);
现在我想要一个通用方法来序列化和反序列化字典到字节数组。 喜欢
public static void Serialize(Dictionary<int, object> dictionary, Stream stream)
{
//Code here
}
和
public static static Dictionary<int, object> Deserialize(Stream stream)
{
//Code here
}
任何人都可以帮我吗?
答案 0 :(得分:3)
试试这个......
public static void Serialize<Object>(Object dictionary, Stream stream)
{
try // try to serialize the collection to a file
{
using (stream)
{
// create BinaryFormatter
BinaryFormatter bin = new BinaryFormatter();
// serialize the collection (EmployeeList1) to file (stream)
bin.Serialize(stream, dictionary);
}
}
catch (IOException)
{
}
}
public static Object Deserialize<Object>(Stream stream) where Object : new()
{
Object ret = CreateInstance<Object>();
try
{
using (stream)
{
// create BinaryFormatter
BinaryFormatter bin = new BinaryFormatter();
// deserialize the collection (Employee) from file (stream)
ret = (Object)bin.Deserialize(stream);
}
}
catch (IOException)
{
}
return ret;
}
// function to create instance of T
public static Object CreateInstance<Object>() where Object : new()
{
return (Object)Activator.CreateInstance(typeof(Object));
}
...用法
Serialize(userSessionLookupTable, File.Open("data.bin", FileMode.Create));
Dictionary<int, UserSessionInfo> deserializeObject = Deserialize<Dictionary<int, UserSessionInfo>>(File.Open("data.bin", FileMode.Open));
我在上面的代码中使用了'Object'来满足您的要求,但我个人会使用'T',它通常表示C#中的通用对象
答案 1 :(得分:1)
二进制序列化
有关详细信息,请查看BinaryFormatter。
这是一个可能的解决方案:
public void Serialize(Dictionary<int, UserSessionInfo> dictionary, Stream stream)
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(dictionary.Count);
foreach (var obj in dictionary)
{
writer.Write(obj.Key);
writer.Write(obj.Value);
}
writer.Flush();
}
public Dictionary<int, UserSessionInfo> Deserialize(Stream stream)
{
BinaryReader reader = new BinaryReader(stream);
int count = reader.ReadInt32();
var dictionary = new Dictionary<int, UserSessionInfo>(count);
for (int n = 0; n < count; n++)
{
var key = reader.ReadInt32();
var value = reader.ReadString();
dictionary.Add(key, value);
}
return dictionary;
}
但您仍需要UserSessionInfo ToString()转换器;
XML 序列化
创建示例类Session
public class Session
{
[XmlAttribute]
public int SessionID;
[XmlAttribute]
public UserSessionInfo SessionInfo;
}
如果要将其序列化为 XML
,则可以创建 XmlSerializerXmlSerializer serializer = new XmlSerializer(
typeof(Session[]),
new XmlRootAttribute() { ElementName = "sessions" }
);
现在您可以序列化或反序列化。
<强>序列化强>
serializer.Serialize(
stream,
dict.Select(kv => new Session(){SessionID = kv.Key, SessionInfo = kv.Info}).ToArray()
);
<强>反序列化强>
var deserialized = (
(Session[])serializer.Deserialize(stream)
).ToDictionary(i => i.id, i => i.info);
但是你需要在UserSessionInfo中使用 ToString()方法将它存储在XML中。
XML可能如下所示:
<sessions>
<session id='int_goes_here' value='string_goes_here'/>
</sessions>
希望这有帮助。
答案 2 :(得分:1)
除非您不想创建文件,否则可以使用MemoryStream
。但是对于序列化方法,如果您不想返回值,则应该将stream
参数标记为[Out]
。
public static void Serialize(Dictionary<int, object> dictionary, [Out] Stream stream)
{
stream = new MemoryStream();
new BinaryFormatter().Serialize(stream, dictionary);
}
public static Dictionary<int, object> Deserialize(Stream stream)
{
return (Dictionary<int, object>)new BinaryFormatter().Deserialize(stream);
}
这将执行二进制序列化。
修改强>
要将其作为字节数组获取,您只需将从Serialize()
方法返回的流转换为MemoryStream
,然后在其上调用.ToArray()
。
这是一个例子:
MemoryStream outputStream;
Serialize(your dictionary here, outputStream);
byte[] bytes = outputStream.ToArray();
答案 3 :(得分:1)
回答可能有点迟,但根据我的经验,这是一个实用且更通用的答案:如果您想快速简便地使用简单的JSON序列化,或者对数据大小或性能的要求不高,请使用简单的JSON序列化。如果您想要高效,快速和跨平台的东西,请使用Google Protocol Buffers。
<div className="intent" id="intent1" style={{border:'1px solid #eee'}}>
<div className="form-group row">
<label htmlFor="intent" className="col-sm-1 col-form-label">Intent</label>
<div className="col-sm-5">
<input type="text" className="form-control" name="indent[]" id="intent1" placeholder="Enter intent"/>
</div>
</div>
</div>
有很多方法可以control the serialisation and use streams and so on。
Json.Net also supports dictionaries too
在c#中有两种使用protobuf的方法:Using .proto message definitions and generate code或reflection based approach using your class definitions and attributes。这取决于您的项目,但我个人更喜欢消息定义。
请注意,您可能必须在序列化和反序列化之前和之后进行自己的调整以与string output = JsonConvert.SerializeObject(myObject);
var copyOfMyObject = JsonConvert.DeserializeObject<MyObject>(output);
一起使用。
.proto文件:
Dictionary
使用Google Protobuf生成代码:
message Person {
int32 id = 1;
string name = 2;
}
Serialise / deserialise using generated classes:
protoc --csharp_out=$DST_DIR $SRC_DIR/person.proto
另外,请您快速了解proto3 is the capability of using JSON可能鲜为人知的功能。
以下是一个快速示例(从protobuf-net page复制)
Person john = ...;
john.WriteTo(stream);
var copyOfJohn = Person.Parser.ParseFrom(stream);
道歉,我有点忽略了关于'二进制'序列化的问题(而不是特定的[ProtoContract]
class Person {
[ProtoMember(1)]
public int Id {get;set;}
[ProtoMember(2)]
public string Name {get;set;}
}
Serializer.Serialize(file, person);
newPerson = Serializer.Deserialize<Person>(file);
问题),因为有很多方法可以使用流来处理流入和流出流程的数据。 C#stream,reader和writer以及其他System.IO APIs都有很好的文档记录。
答案 4 :(得分:0)
除非您想构建自己的完全自定义序列化程序,否则您需要使用内置的serialization structure
字典和所有引用的类型必须实现内置的序列化结构,该结构要求使用正确的属性(即[Serializable]
或[DataContact]
来装饰类,并且对象无法实现它您无法直接将其序列化,您需要将其更改为可序列化类型