2016-09-19 126 views
0

我有一个对象/类有不同的值作为成员,所有可序列化,我可以将一个对象转换为一个字节[]和其他方式。 我正在将这些对象的列表转换为一个大字节数组,我如何将它转换回来?C#将一个对象的字节数组转换为对象列表

实施例目的:

using System; 
using System.IO; 

[Serializable] 
public class MyItem { 
    internal string m_name = ""; 
    internal int m_position = 0; 
    internal float m_color = 0f; 
    internal int m_direction = 0; 
    internal float m_power = 0f; 

    public MyItem(string name, int position, float color, int direction, float power) { 
     m_name = name; 
     m_position = position; 
     m_color = color; 
     m_direction = direction; 
     m_power = power; 
    } 

    public byte[] Serialize() { 
     using (MemoryStream m = new MemoryStream()) { 
      using (BinaryWriter writer = new BinaryWriter(m)) { 
       writer.Write(m_name); 
       writer.Write(m_position); 
       writer.Write(m_color); 
       writer.Write(m_direction); 
       writer.Write(m_power); 
      } 
      return m.ToArray(); 
     } 
    } 

    public static MyItem Desserialize(byte[] data) { 
     string name; 
     int position; 
     float color; 
     int direction; 
     float power; 

     using (MemoryStream m = new MemoryStream(data)) { 
      using (BinaryReader reader = new BinaryReader(m)) { 
       name = reader.ReadString(); 
       position = reader.ReadInt32(); 
       color = reader.ReadSingle(); 
       direction = reader.ReadInt32(); 
       power = reader.ReadSingle(); 
      } 
     } 

     return new MyItem(name, position, color, direction, power); 
    } 
} 

,并转换到字节数组:

List<MyItem> itemlist = <...>; 
List<byte[]> byteList = new List<byte[]>(); 
for (int i = 0; i < itemlist.Count; i++) { 
    byteList.Add(itemlist[i].Serialize()); 
} 
byte[] data = byteList.SelectMany(bytes => bytes).ToArray(); 

转换回:

???????? 
+0

您将不得不将聚合数组拆分为序列化对象大小的块,然后反序列化。 – itsme86

+0

由于不在项目之间放置任何标记,因此必须计算单个项目的字节大小,将数据拆分为该大小的块,然后分别处理每个块。 – kiziu

+0

您需要将对象数组直接序列化,然后才能将整个数组进行反序列化。 (注意,这是基于切换到.NET的序列化的整个事情:不是你自己的东西,但仍然标记类型,如果使用内置序列化。) – Richard

回答

1

正如在注释中规定,需要编写的字节流中的每个对象都能够反序列化单个对象。例如:

public static class MyItemSerializer 
{ 
    public static byte[] Serialize(this IEnumerable<MyItem> items) 
    { 
     using (MemoryStream m = new MemoryStream()) 
     { 
      using (BinaryWriter writer = new BinaryWriter(m, System.Text.Encoding.UTF8, true)) 
      { 
       foreach (var item in items) 
       { 
        var itemBytes = item.Serialize(); 
        writer.Write(itemBytes.Length); 
        writer.Write(itemBytes); 
       } 

      } 

      return m.ToArray(); 
     } 
    } 

    public static List<MyItem> Deserialize(byte[] data) 
    { 
     var ret = new List<MyItem>(); 
     using (MemoryStream m = new MemoryStream(data)) 
     { 
      using (BinaryReader reader = new BinaryReader(m, System.Text.Encoding.UTF8)) 
      { 
       while (m.Position < m.Length) 
       { 
        var itemLength = reader.ReadInt32(); 
        var itemBytes = reader.ReadBytes(itemLength); 
        var item = MyItem.Desserialize(itemBytes); 
        ret.Add(item); 
       } 
      } 
     } 

     return ret; 
    } 
} 

在这里,你可以看到它在行动:https://dotnetfiddle.net/Nk2cks

但.NET已经包含了一个名为BinaryFormatter

Protobuf由谷歌串是另一种可能性。

+0

为什么你离开BinaryWriter打开? –

+0

如果'BinaryWriter'关闭了'MemoryStream',则以后某些函数无效。但['ToArray()'](http://stackoverflow.com/questions/3981253/is-calling-memorystream-toarray-dangerous-after-disposing)仍然有效。所以,如果你关闭它就没关系,我的错误。 – Nico

相关问题