2009-04-29 9 views
11

Nehmen wir an, ich habe eine Datei, die ein serialisiertes Objekt von BinaryFomatter enthält. Jetzt möchte ich in der Lage sein, ein anderes Objekt zu serialisieren und dieses an der vorhandenen Datei anzuhängen.Wie wird in vorhandene Datei serialisiert?

Wie kann ich es tun?

Antwort

2

Zuerst, was Sie wirklich brauchen, ist ein Array von Objekt zu speichern - legen Sie sie in einen Container und serialisieren den Container, wie bereits erwähnt.

Nun, wenn Sie wirklich in einer einzigen Datei verkettet, um zwei serialisierte Objekt wollen:

bin ich nicht sicher, dass dies möglich ist „out of the box“, aber Sie können zwei Dinge tun.

  1. verwenden oder Ihr eigenes semi-TAR-Datei-Format erfinden, in dem du einen kleinen Header am Anfang (oder Ende) der Datei schreiben, die den Inhalt der Datei (# 'Objekte beschreiben, und Größen).

  2. Schreiben Sie einen C# -Code, um den Anfang und das Ende jedes serialisierten Objekts selbst zu erkennen. Ich bin mir nicht ganz sicher, ob das möglich ist. Here ist eine nicht offizielle Dokumentation des Serialisierungsformats. Es enthält Header, jedoch gibt es keine Garantie, dass dieser Header nicht in der Datei erscheint.

2

Wie geht es diese

deserialise den Inhalt der ersten Datei in ein Objekt im Speicher, das erste Objekt zu einer Sammlung (zB Liste <YourObjectType>), fügen Sie Ihr neues Objekt zu dieser Sammlung, serialise dann die Sammlung (enthält jetzt zwei Objekte) über der vorhandenen Datei.

4

Versetzen Sie Ihre Objekte in ein Sammlungsobjekt und serialisieren Sie es so. Wenn Sie eine binäre Repräsentation eines Objekts am Ende einer vorhandenen Datei anhängen würden, würden Sie Probleme haben, es zurückzulesen.

+0

Ich bin sicher, das ist, was ich gerade gesagt habe – tomfanning

+1

Sicher, das ist das Gleiche. Erinnern Sie sich jedoch, dass es möglich ist, eine Antwort gleichzeitig zu schreiben und sie fast gleichzeitig zu veröffentlichen, ohne die anderen Antworten zu sehen. ;) – paweloque

+0

Ich vermute ja :-) – tomfanning

3

Wenn Sie nur den Stream zum Schreiben öffnen und den Zeiger am Ende des Streams positionieren, können Sie ein anderes Objekt serialisieren und es wird an den vorhandenen Stream angehängt.

Deserialisierung wird auch über das Objekt hinauslesen, aber nicht weiter.

Offensichtlich, wenn Sie einen zufälligen Zugriff auf Ihre Objekte haben möchten (deserialize Objekt Nr. 17, aber nicht alles davor), dann benötigen Sie einen Index der Positionen, wo jedes Objekt startet, aber wenn Sie nur alle Objekte lesen möchten Von Anfang an können Sie sie einfach hintereinander serialisieren.

+0

Und wie würdest du es später deserialisieren? Sind Sie sicher, dass .NET die serialisierte Objektgröße aus den Headern kennt? –

+0

Das ist eine sehr gute Frage. Ich bezweifle es sehr. –

+0

Aber ja, tut es. –

19

Dies ist in der Tat möglich. Der folgende Code hängt das Objekt an.

using (var fileStream = new FileStream("C:\file.dat", FileMode.Append)) 
{ 
    var bFormatter = new BinaryFormatter(); 
    bFormatter.Serialize(fileStream, objectToSerialize); 
} 

Der folgende Code de-serialisiert die Objekte.

var list = new List<ObjectToSerialize>();  

using (var fileStream = new FileStream("C:\file.dat", FileMode.Open)) 
{ 
    var bFormatter = new BinaryFormatter(); 
    while (fileStream.Position != fileStream.Length) 
    { 
     list.Add((ObjectToSerialize)bFormatter.Deserialize(fileStream)); 
    } 
} 

Hinweis zu diesem Zweck muss die Datei nur die gleichen Objekte enthalten.

+0

Haben Sie diesen Code versucht? Es scheint, dass es nur den Teil deserialisiert, der zuletzt angehängt wurde. Hier ist mein Testcode http://pastebin.com/EV4rPaT4 – mrgloom

+1

Hallo Mrgloom. Das ist fast 4 Jahre alt, aber es wurde in der Produktion ohne Probleme verwendet. Ich habe mir deinen Testcode angesehen. Sie serialisieren 3 separate Listen, die nicht an eine vorhandene angehängt sind. Bei der Deserialisierung überschreiben Sie jedes Listenobjekt mit dem neuesten. Versuchen Sie, die Zeile 22 in list.AddRange zu ändern ((Liste ) bFormatter.Deserialize (fileStream)); Viel Glück. – Magpie

+0

Danke, es funktioniert super! Ich weiß zwar nicht warum:/Wie kann bFormatter.Deserialize wissen wann ein ObjectToSerialize in der Datei endet? Während des Debuggens stoppt fileStream.Position genau an der Position, an der jedes ObjectToSerialize in der Datei endet, und ich kann nicht herausfinden, warum ... – Loaderon

Verwandte Themen