C# writing object to binary file
I have to write an object in to binary file.My struct looks like this.
Struct Company
{
int numberofemployees
list of Struct Employee.
}
Struct Employee
{
string EmployeeName;
string Designation;
}
What is the best way to do the above oper开发者_JAVA百科ation? Regards Raju
In my understanding, BinaryFormatter is the tool for this job.
Edit: As Marc explains in the comments, BinaryFormatter has certain disadvantages. He recommends protobuf-net in his blog.
What exactly do you want the output to look like? You can write it manually (see Lirik's answer), or if you want runtime support, perhaps something like protobuf-net.
This would be trivial to do if you were using classes (which I expect you actually should be), but additionally protobuf-net v2 (only available as source at the moment) should work with that "as is".
For info, here is how I would do it as classes:
public class Company
{
private readonly List<Employee> employees = new List<Employee>();
public List<Employee> Employees { get { return employees;}}
}
public class Employee
{
public string EmployeeName {get;set;}
public string Designation {get;set;}
}
This could be decorated with serialization attributes, or (again, using protobuf-net v2) something like this test (which passes):
[Test]
public void CanSerializeCompany()
{
var model = TypeModel.Create();
model.Add(typeof(Company), false).Add("Employees");
model.Add(typeof(Employee), false).Add("EmployeeName", "Designation");
model.CompileInPlace();
Company comp = new Company {
Employees = {
new Employee { Designation = "Boss", EmployeeName = "Fred"},
new Employee { Designation = "Grunt", EmployeeName = "Jo"},
new Employee { Designation = "Scapegoat", EmployeeName = "Alex"}}
}, clone;
using(var ms = new MemoryStream()) {
model.Serialize(ms, comp);
ms.Position = 0;
Console.WriteLine("Bytes: " + ms.Length);
clone = (Company) model.Deserialize(ms, null, typeof(Company));
}
Assert.AreEqual(3, clone.Employees.Count);
Assert.AreEqual("Boss", clone.Employees[0].Designation);
Assert.AreEqual("Alex", clone.Employees[2].EmployeeName);
}
(and writes 46 bytes)
It should work with private fields, structs, etc - I'd have to take a look...
If you are able to add attributes, then you don't need to set up the model manually (the first 4 lines). The rest of the code is just showing full round-trip usage.
Here is an example how you can read/write a binary file:
using System;
using System.IO;
public class BinaryFileTest {
private static void Main() {
FileStream fs = new FileStream("test.dat", FileMode.Create);
BinaryWriter w = new BinaryWriter(fs);
w.Write(1.2M);
w.Write("string");
w.Write("string 2");
w.Write('!');
w.Flush();
w.Close();
fs.Close();
fs = new FileStream("test.dat", FileMode.Open);
StreamReader sr = new StreamReader(fs);
Console.WriteLine(sr.ReadToEnd());
fs.Position = 0;
BinaryReader br = new BinaryReader(fs);
Console.WriteLine(br.ReadDecimal());
Console.WriteLine(br.ReadString());
Console.WriteLine(br.ReadString());
Console.WriteLine(br.ReadChar());
fs.Close();
}
}
精彩评论