C#类到字节流
将我的类转换为字节数组或从字节数组转换为字节数组的正确方法是什么?我希望能够尽可能简单地将其保存到文件中 我应该将其序列化吗?C#类到字节流,c#,C#,将我的类转换为字节数组或从字节数组转换为字节数组的正确方法是什么?我希望能够尽可能简单地将其保存到文件中 我应该将其序列化吗? 我应该只提供一个返回字节数组的函数吗?或者是记忆流? 还有别的吗 我不太熟悉C#文件处理,因此如果答案也能说明将二进制数据写入文件的常见方式,我将不胜感激 编辑我从答案中看出我被误解了。我有课。我有一种格式,我想用二进制格式保存它。我想知道公开这种二进制表示的正确方法是什么。我需要完全控制格式,而不是.NET为我这样做(我稍后将在c++中阅读它)如果您指的是如何使用二进
我应该只提供一个返回字节数组的函数吗?或者是记忆流?
还有别的吗 我不太熟悉C#文件处理,因此如果答案也能说明将二进制数据写入文件的常见方式,我将不胜感激
编辑我从答案中看出我被误解了。我有课。我有一种格式,我想用二进制格式保存它。我想知道公开这种二进制表示的正确方法是什么。我需要完全控制格式,而不是.NET为我这样做(我稍后将在c++中阅读它)如果您指的是如何使用二进制序列化来序列化类,您可以查看以下代码:
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
接口
您可以使用。请注意,您的类必须是这样才能工作的
private byte[] ToByteArray(object source)
{
var formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, source);
return stream.ToArray();
}
}
看,这很容易理解,并开始编写代码以立即看到结果。但是,在阅读完不同的文章后,自然会选择最符合您需要的主题。按优先顺序: 1) 如果您的应用程序支持数据库,则将希望“记住”的数据存储到数据库中 2) 简单的平面文件或XML文件(即“不序列化:只保存状态”) 3) 否则,序列化可能就是您想要的 以下是有关.Net序列化的链接: 下面是关于序列化为XML(而不是二进制)的链接: 再次—我强烈建议将“序列化”作为最后手段(如果可能的话,尽可能简单、可靠地“保存状态”),并将“二进制序列化”作为最后手段(除非您有很好的理由不这样做) 我想 将关键数据作为文本写入磁盘总是很危险的。任何匿名用户都可以打开文本文件并轻松读取您的数据。通过对象序列化,可以在一定程度上减少这种危险。您可以将任何复杂对象直接写入文件流,而无需将单个属性的值转换为文本。您可以将数据写入磁盘,至少使其不可读。为了让用户读取您的数据文件,他们必须使用您的程序。类似于应用程序中提供的文件打开命令 序列化是将复杂对象转换为字节流进行存储的过程反序列化是其反向过程,即将字节流解压为其原始形式。用于读取和写入文件的命名空间是System.IO。对于序列化,我们将查看System.Runtime.Serialization命名空间。ISerializable接口允许您将任何类序列化。有很好的例子
如上所述,序列化是转换 对象转换为字节流,以便将其持久化到内存中 数据库或文件。它的主要目的是拯救一个国家 对象,以便能够在需要时重新创建它。相反 这个过程称为反序列化 序列化的工作原理 下图显示了序列化的整个过程 对象被序列化为一个流,该流不仅承载数据, 但是有关对象类型的信息,例如其版本、区域性、, 和程序集名称。从该流中,它可以存储在数据库中,即 文件或内存。看
为了响应您的编辑,并且考虑到您拥有二进制格式并且需要自己控制它,我看到了两个选项:
- 一种接受流并将二进制表示写入流的方法
- 返回字节数组的方法
- 一种方法,它接受类型的实例和流,并将二进制表示形式写入流
- 一种方法,它接受类型的实例并返回字节数组
每对的第一个选项可能会给你更多的灵活性;根据您的需要,您可以传递文件流、内存流或其他内容。Google.NET中的“二进制序列化”。简单的参考物质。@ Bunc:如果你需要一个完整的控件A<代码>原Buff(在我的回答中有一个可能的选择)。@ TiGRAN澄清:ToBuf不提供“完全控制”,但是它在C++和C++之间是非常可移植的。@ McCravell:好的,但是“完全控制”意味着,基本上,从斯特拉奇那里写些东西。这里我的意思是“足够灵活”。@Tigran,我完全同意;像protobuf这样的可移植的东西可以节省baruch大量的时间和bug。我希望能够序列化我的类,并且我希望控制序列化的格式。您可以使用XML格式或二进制格式序列化您的类。您能解释一下使用平面文件“保存状态”是什么意思吗?我不明白这和二进制序列化之间的区别。
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();
}
}