Serialisierung von Klassen

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von xtts02.

    Serialisierung von Klassen

    Hallo zusammen.
    Ich serialisiere eine Klasse mithilfe des eines BinaryFormatters. Meine Fragen sind nun:
    • Kann ich dem Dateityp meiner serialisierten Klasse nun ein Icon zuweisen?
    • Kann ich dem Dateityp meiner serialisierten Klasse ein "Öffnen mit ..." im Kontextmenü hinzufügen?
    Vielen Dank,
    TheoTechnic
    Sehr gutes Thema.
    Ich habe mal fix einen OpenFileDialog hinzugefügt, da kommt aber bei bf.Serialize() der Fehler

    Quellcode

    1. Der Typ "System.Windows.Forms.OpenFileDialog" ... ist nicht als serialisierbar gekennzeichnet.

    Also: Wir können nur <Serializable()>-Objekte hinzufügen.
    Sehen wir weiter.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    TheoTechnic schrieb:

    Kann ich dem Dateityp meiner serialisierten Klasse ein "Öffnen mit ..." im Kontextmenü hinzufügen?

    Ja kannst Du indem Du den Registry Wert HKEY_CURRENT_USER\ Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ FileExts\ <Dateiendung>\ entsprechend anpasst. Wie genau findest Di z.B. hier

    Aber warum ein "Öffnen mit..." und nicht gleich das Programm angeben, mit dem Du solche Dateien grundsätzlich öffnen möchtest. Dabei muss Du nur die Extension in die Registry HKeyClassesRoot eintragen und einen Unterschlüssel command hinzufügen. Dein programm kann dann beim Öffnen den Filenamen als Argument auslesen.

    Beispiele findest Du dazu hier genügend im Forum, oder auch hier bei CodeProject
    @ Kangaroo
    Vielen, vielen Dank, wie immer eine Top Antwort :)


    Jetzt habe ich nur noch ein (unerwartetes) Problem. Mit diesem Code deserialisiere ich meine Datei:

    VB.NET-Quellcode

    1. Dim cls As MyClass = New MyClass ()
    2. Dim fs As New FileStream("C/User/...", FileMode.Open)
    3. Dim formatter As New BinaryFormatter
    4. fs.Close()
    5. cls = DirectCast(formatter.Deserialize(fs), MyClass)

    Leider bekomme ich dabei aber eine "schöne" Exception:
    Exception

    Exception schrieb:


    System.Runtime.Serialization.SerializationException wurde nicht behandelt.
    Message="Das Streamende wurde erreicht, bevor die Verarbeitung abgeschlossen wurde."
    Source="mscorlib"
    StackTrace:
    bei System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
    bei System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
    bei BloxBuilder.Level.load(String filename) in C:\Users\Konrad\Documents\Visual Studio 2008\Projects\BloxBuilder\BloxBuilder\Level.vb:Zeile 29.
    bei BloxBuilder.Form1.NeonButton1_Load() in C:\Users\Konrad\Documents\Visual Studio 2008\Projects\BloxBuilder\BloxBuilder\Form1.vb:Zeile 233.
    bei BloxBuilder.NeonButton.Label1_Click(Object sender, EventArgs e) in C:\Users\Konrad\Documents\Visual Studio 2008\Projects\BloxBuilder\BloxBuilder\NeonButton.vb:Zeile 29.
    bei System.Windows.Forms.Control.OnClick(EventArgs e)
    bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.Label.WndProc(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    bei BloxBuilder.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:Zeile 81.
    bei System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
    bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    bei System.Threading.ThreadHelper.ThreadStart()
    InnerException:
    Nothing

    TheoTechnic schrieb:

    Leider bekomme ich dabei aber eine "schöne" Exception:

    Bei Dir nehme ich mal an Du hattest nen schlechten Tag ( oder eine lange Nacht ) , sonst würdest Du den Stream nicht vor dem Deserialize schliessen ... :rolleyes:

    Übrigens was manchmal auch nett ist wenn man Speicherplatz sparen will (übers Netzwerk schicken) den Stream noch zusätzlich zu zippen:

    VB.NET-Quellcode

    1. Dim fs As Stream = New FileStream(fullPath, FileMode.OpenOrCreate)
    2. Dim bf As New BinaryFormatter
    3. ' use optional compression
    4. If compression Then fs = New GZipStream(fs, CompressionMode.Compress)
    5. bf.Serialize(fs, instance)
    6. fs.Close()

    Kangaroo schrieb:

    Bei Dir nehme ich mal an Du hattest nen schlechten Tag ( oder eine lange Nacht ) , sonst würdest Du den Stream nicht vor dem Deserialize schliessen ...

    Ja, da hast du recht ^^
    Leider existiert der Fehler auch nach der Änderung noch :pinch:

    VB.NET-Quellcode

    1. Dim cls As MyClass = New MyClass ()
    2. Dim fs As New FileStream("C/User/...", FileMode.Open)
    3. Dim formatter As New BinaryFormatter
    4. cls = DirectCast(formatter.Deserialize(fs), MyClass)
    5. fs.Close()
    hallo,

    ich hab ein problem beim serialisieren meiner klasse. benutze vb.net 2010express

    VB.NET-Quellcode

    1. <Serializable()>
    2. Public Class saver
    3. Dim xm As String
    4. Dim xml As New Serialize
    5. Dim obj1 As saver
    6. Public Sub save(ByVal path As String)
    7. xm = "test"
    8. obj1 = New saver
    9. xml.XMLSerialize(xm, path)
    10. End Sub
    11. Public Sub load(ByVal path As String)
    12. xm = " "
    13. xm = xml.XMLDeSerialize(Of saver)(path)
    14. MsgBox(xm)
    15. End Sub
    16. End Class


    das ist meine klasse. und hier ist die eigentliche serialisierung

    VB.NET-Quellcode

    1. Public Class Serialize
    2. Public Sub XMLSerialize(ByVal Obj As Object, ByVal FileName As String)
    3. Dim XML As New XmlSerializer(Obj.GetType)
    4. 'Dim XML As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    5. Dim FS As New FileStream(FileName, FileMode.Create)
    6. XML.Serialize(FS, Obj)
    7. FS.Close()
    8. End Sub
    9. Public Function XMLDeSerialize(Of T)(ByVal FileName As String) As Object
    10. Dim XML As New XmlSerializer(GetType(T))
    11. Dim FS As New FileStream(FileName, FileMode.Open)
    12. Dim RetObj As Object = XML.Deserialize(FS)
    13. FS.Close()
    14. Return RetObj
    15. End Function
    16. End Class


    wie man an meiner auskommentierten zeile sieht, hab ich es auch schon mit binaryformatter versucht.

    das problem ist folgendes:
    in der xml datei nun folgendes drinne:

    XML-Quellcode

    1. <?xml version="1.0"?>
    2. <string>test</string>


    wenn ich aber anstatt

    VB.NET-Quellcode

    1. xml.XMLSerialize(xm, path)

    VB.NET-Quellcode

    1. xml.XMLSerialize(obj1, path)

    schreibe, steht im xml dokument nur

    XML-Quellcode

    1. <?xml version="1.0"?>
    2. <saver xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />


    somit steht im xml dokument nicht die variable "xm = "test"" welche dann auch nicht geladen wird.
    kann mir jemand sagen, was ich falsch mache?

    danke