2010-04-08 12 views
7

Ich muss ein Objekt in Binärdatei schreiben. Meine Struktur sieht so aus.C# Objekt in Binärdatei schreiben

Struct Company 
    { 
     int numberofemployees 
     list of Struct Employee. 
    } 

    Struct Employee 
    { 
     string EmployeeName; 
     string Designation; 
    } 

Was ist der beste Weg, um den obigen Vorgang zu tun? Grüße Raju

+4

Warum ist das eine Struktur? Das sieht nicht nach einer guten Verwendung für "struct" aus, und ich nehme an, dass es dich auf interessante Weise beißen wird. Ich würde hier eine 'Klasse' verwenden ... –

Antwort

7

Was genau wollen Sie die Ausgabe so aussehen? Sie können es manuell schreiben (siehe Liriks Antwort), oder wenn Sie Runtime-Unterstützung wünschen, vielleicht etwas wie protobuf-net.

Dies wäre trivial zu tun, wenn Sie Klassen verwenden (was ich erwarte, dass Sie eigentlich sein sollten), aber zusätzlich Protobuf-Net v2 (nur als Quelle im Moment verfügbar) sollte mit "wie es ist" arbeiten.

Für Informationen, hier ist, wie ich es als Klassen tun würde:

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;} 
    } 

Dieses mit Serialisierung Attribute eingerichtet werden könnte, oder (wieder protobuf-net v2 verwenden) so etwas wie dieser Test (was passiert) :

[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); 
    } 

(und schreibt 46 Byte)

Es sollte Arbeit mit privaten Feldern, Strukturen, usw. - ich würde eine Toilette nehmen k ...

Wenn Sie Attribute hinzufügen können, müssen Sie das Modell nicht manuell einrichten (die ersten 4 Zeilen). Der Rest des Codes zeigt nur die vollständige Round-Trip-Nutzung an.

9

In meinem Verständnis ist BinaryFormatter das Werkzeug für diesen Job.

Bearbeiten: Wie Marc in den Kommentaren erklärt, hat BinaryFormatter bestimmte Nachteile. Er empfiehlt protobuf-net in seinem Blog.

+0

+1 Jens, das sieht besser aus als einfach selbst in die Datei zu schreiben. – Kiril

+0

Ich habe versucht, Binary Formatter zu verwenden. Es fügt einen Header hinzu, bevor das erste Objekt in die Datei geschrieben wird. Ich möchte keine Kopfdaten. – user209293

+1

Ja, Sie haben die Chance, die Daten eines Tages richtig zu lesen. –

5

Here is an example, wie man lesen kann/schreiben eine Binärdatei:

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(); 

    } 
}