C#类到字节流

时间:2012-01-04 21:43:46

标签: c#

将类转换为字节数组的正确方法是什么?我希望能够尽可能简单地将其保存到文件中。

我应该将其序列化吗? 我应该只提供一个返回字节数组的函数吗?或者也许是MemoryStream? 还有别的吗?

我对C#文件处理并不十分熟悉,所以如果答案也能说明将二进制数据写入文件的常用方法,我将不胜感激。

编辑我从答案中看到我被误解了。我上课了。我有一种格式我想以二进制形式保存它。我想知道公开这个二进制表示的正确方法是什么。我需要完全控制格式,而不是.NET为我做的(我将在稍后用c ++阅读)

6 个答案:

答案 0 :(得分:3)

查看Protobuf,它很容易理解并开始编码以立即查看结果。但之后,自然会阅读不同的文章,根据您的需要选择最佳匹配。

答案 1 :(得分:3)

按优先顺序排列:

1)如果您的应用程序是数据库感知的,那么将您想要“记住”的数据存储到数据库中。

2)一个简单的平面文件或XML文件(即“不要序列化:只保存状态”)

3)否则,序列化可能就是你要找的东西

这是.Net序列化的链接:

http://msdn.microsoft.com/en-us/library/ms973893.aspx

这是关于序列化为XML(而不是二进制)的链接:

http://support.microsoft.com/kb/815813

using System;

public class clsPerson
{
  public  string FirstName;
  public  string MI;
  public  string LastName;
}

class class1
{ 
   static void Main(string[] args)
   {
      clsPerson p=new clsPerson();
      p.FirstName = "Jeff";
      p.MI = "A";
      p.LastName = "Price";
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
      x.Serialize(Console.Out, p);
      Console.WriteLine();
      Console.ReadLine();
   }
}    

再次 - 我强烈建议将“序列化”作为最后的手段(如果可能的话,尽可能简单而强大地“保存状态”),并将“二进制序列化”作为非常有道理的(除非你有充分的理由)否则)。

... IMHO

答案 2 :(得分:2)

您可以使用BinaryFormatter。请注意,您的课程必须为[Serializable]才能生效。

private byte[] ToByteArray(object source)
{
    var formatter = new BinaryFormatter();
    using (var stream = new MemoryStream())
    {
        formatter.Serialize(stream, source);                
        return stream.ToArray();
    }
}

答案 3 :(得分:2)

为了回应您的编辑,并且鉴于您拥有二进制格式并需要自己控制它,我看到两个选项:

  • 接受流并将二进制表示写入流
  • 的方法
  • 返回字节数组的方法

当然,您可以通过使用

创建另一个类来将其与类型本身分离
  • 接受您的类型实例和流并将二进制表示写入流
  • 的方法
  • 接受类型实例并返回字节数组的方法

每对的第一个选项可能会给你更多的灵活性;您可以根据需要传递文件流或内存流等。

答案 4 :(得分:1)

  

将关键数据作为TEXT写入磁盘始终是危险的。任何匿名用户都可以打开文本文件并轻松读取您的数据。使用对象序列化,您可以在一定程度上减少这种危险。您可以将任何复杂对象直接写入 filestream ,而无需将各个属性的值转换为文本。您可以将数据写入磁盘,至少不是人类可读的。为了让用户读取您的数据文件,他们必须使用您的程序。就像您可以在应用程序中提供的文件打开命令一样。

     

序列化是将复杂对象转换为字节流以进行存储的过程。 反序列化是它的反向过程,即将字节流解包为其原始形式。用于读写文件的命名空间是System.IO。对于序列化,我们将查看System.Runtime.Serialization命名空间。 ISerializable 界面允许您创建任何类Serializable。 See有很好的例子。


  

如上所述,序列化是转换的过程   将对象转换为字节流以便将其持久化到内存中,a   数据库或文件。它的主要目的是拯救一个国家   对象,以便能够在需要时重新创建它。相反   进程称为反序列化

     

序列化工作原理

     

下图显示了序列化的整个过程。

     

enter image description here

     

将对象序列化为流,该流不仅包含数据,   但有关对象类型的信息,例如版本,文化,   和程序集名称。从该流中,它可以存储在数据库中,a   文件或内存。请参阅MSDN

答案 5 :(得分:0)

如果您的意思是如何使用二进制序列化序列化类,您可以查看下面的代码:

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace BinarySerializationTest
{
    class Program
    {
        static void Main(string[] args)
        {

            // Serialization of String Object   

            String writeData = "Microsoft .NET Framework 4.0";
            FileStream writeStream = new FileStream("C:\\StringObject.data", FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(writeStream, writeData);
            writeStream.Close();

            // Deserialization of String Object

            FileStream readStream = new FileStream("C:\\StringObject.data", FileMode.Open);
            String readData = (String) formatter.Deserialize(readStream);
            readStream.Close();
            Console.WriteLine(readData);

            Console.Read();
        }
    }
}

在此示例中,我序列化了一个字符串,但您可以序列化“任何对象”。您需要做的就是在您的课程中添加属性[Serializable]

[Serializable]
public class Car
{
    public string Make;
    public string Model;

}

如果要实现自定义序列化,则您的类需要实现ISerializable接口

http://msdn.microsoft.com/en-us/library/ms182342(v=VS.100).aspx