Public Structure BinCP42
Dim set_code As Long
Dim channel_sel_Low As Byte
Dim name As string ' feste Länge 15 Zeichen
dim channel_s(15) As Byte
dim channel_link_s(17) As Byte
dim subchan_s(15, 15) As Byte
end structure
|
[Serializable]
public class BinCP42
{
public long set_code { get; set; }
public byte channel_sel_Low { get; set; }
public string name { get; set; }
// usw. usw.
public void Save(string path)
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, this);
stream.Close();
}
public static BinCP42 Load(string path)
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
BinCP42 obj = (BinCP42)formatter.Deserialize(stream);
stream.Close();
return obj;
}
}
// Erzeugen und speichern
BinCP42 b42 = new BinCP42();
b42.channel_sel_Low = 1;
b42.name = "Test";
b42.set_code = 100;
b42.Save("C:\temp\b42.bin");
// Wieder laden
BinCP42 b42Load = BinCP42.Load("C:\temp\b42.bin");
<Serializable> _
Public Class BinCP42
Public Property set_code() As Long
Get
Return m_set_code
End Get
Set
m_set_code = Value
End Set
End Property
Private m_set_code As Long
Public Property channel_sel_Low() As Byte
Get
Return m_channel_sel_Low
End Get
Set
m_channel_sel_Low = Value
End Set
End Property
Private m_channel_sel_Low As Byte
Public Property name() As String
Get
Return m_name
End Get
Set
m_name = Value
End Set
End Property
Private m_name As String
' usw. usw.
Public Sub Save(path As String)
Dim formatter As IFormatter = New BinaryFormatter()
Dim stream As Stream = New FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None)
formatter.Serialize(stream, Me)
stream.Close()
End Sub
Public Shared Function Load(path As String) As BinCP42
Dim formatter As IFormatter = New BinaryFormatter()
Dim stream As Stream = New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
Dim obj As BinCP42 = DirectCast(formatter.Deserialize(stream), BinCP42)
stream.Close()
Return obj
End Function
End Class
' Erzeugen und speichern
Dim b42 As New BinCP42()
b42.channel_sel_Low = 1
b42.name = "Test"
b42.set_code = 100
b42.Save("C:\temp\b42.bin")
' Wieder laden
Dim b42Load As BinCP42 = BinCP42.Load("C:\temp\b42.bin")
|
1 |
Bei der Serialisierung von Objekten muss man beachten, dass bei Änderungen an der Struktur der Klasse (z.B. Hinzufügen von Properties) alte serialisierte Objekte nicht mehr gelesen werden können. Es gibt aber einen Versionierungs-Mechanismus, mit dem man dieses Problem umgehen kann. Leider habe ich auf die schnelle kein adäquates Beispiel gefunden, folgender Link bietet aber einen Einstieg: http://msdn.microsoft.com/en-us/library/ms973893.aspx
– luedi 17.01.2013
|
|
2 |
Wenn man Klassen serialisiert, dann aber bitte nie mit den Auto- Properties arbeiten: { get; set; }
Die kann man später u. U. nicht mehr deserialisieren. Siehe: http://codekicker.de/fragen/geht-binaerer-Serialisierung-Nachtraegliche-Aenderungen-Property – Xantiva 21.01.2013
|
|
2 |
@Xantiva: Das stimmt, sollte man nicht tun. Hatte ich hier aber auch nur gemacht um den Code möglichst kurz zu halten. Und es passiert ja wirklich nur dann, wenn man die Properties verändert.
– JEwen 21.01.2013
|
<Serializable()>
Public Structure BinCP42
Dim set_code As Long
Dim channel_sel_Low As Byte
<VBFixedString(15)>
Dim name As String ' feste Länge 15 Zeichen
'Arrays nicht mit fester Größe in Strukturvariablen
<VBFixedArray(15)>
Dim channel_s() As Byte
<VBFixedArray(17)>
Dim channel_link_s() As Byte
<VBFixedArray(15, 15)>
Dim subchan_s(,) As Byte
Sub New(ByVal i As Boolean)
If i Then
ReDim channel_s(15)
ReDim channel_link_s(17)
ReDim subchan_s(15, 15)
End If
End Sub
End Structure
Private Sub SaveStructure2BinaryFile(ByVal s As BinCP42)
Dim file As String = "C:\DATA.BIN"
Dim objFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim fstream As New System.IO.FileStream(file, System.IO.FileMode.Create)
objFormatter.Serialize(fstream, s)
fstream.Close()
End Sub
Private Sub LoadBinaryFile2Structure(ByRef s As BinCP42)
Dim file As String = "C:\DATA.BIN"
If System.IO.File.Exists(file) Then
Dim objFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim fstream As New System.IO.FileStream(file, System.IO.FileMode.Open)
s = objFormatter.Deserialize(fstream)
fstream.Close()
End If
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim values As New BinCP42(True)
With values
.set_code = 123
.channel_sel_Low = 3
.name = "Test"
.channel_s(0) = 12
.channel_s(1) = 21
.channel_link_s(0) = 33
.subchan_s(0, 0) = 5
End With
'Datenstruktur speichern
SaveStructure2BinaryFile(values)
'und in neue Variable einlesen
Dim values2 As New BinCP42(True)
LoadBinaryFile2Structure(values2)
End Sub
|
Ich möchte darauf hinweisen, dass das VBFixedString Attibut ab .NET Framework 4.0 als Deprecated markiert ist.
– luedi 18.01.2013
|
||
1 |
Hm, warum nicht, so geht es natürlich auch. Der 'Umweg' über die Klasse kommt mir dabei aber wesentlich einfacher, strukturierter und kürzer vor.
– JEwen 18.01.2013
|
|
Hallo Claus,
danke für den Ansatz. Ich habe das Beispiel mal übernommen und schreibt tatsächlich Daten weg. Das trifft nur nicht ganz meiner Vorstellung. Den Binärfile, den ich schreiben muß, ist ein fester Code, um ein Meßgerät zu programmieren, da kann ich die Variablennamen im File nicht gebrauchen. Es sollen einfach nur die VariablenWerte in der Reihenfolge geschrieben werden. Wie mache ich das ? Oder muß ich einen anderen Ansatz wählen. hupsi – hupsi 23.01.2013
|
|
Public Property set_code() As Long
Get
Return m_set_code
End Get
Set
m_set_code = Value
End Set
End Property
Public Property set_code() As Long [= Standardwert]
|
|
Module Module1
<Serializable()>
Public Structure BinCP42
Dim set_code As Int32 'Long
Dim channel_sel_Low As Byte
Dim channel_sel2_Low As Byte
<VBFixedString(15)>
Dim name As String ' feste Länge 15 Zeichen'Arrays nicht mit fester Größe in Strukturvariablen
<VBFixedArray(15)>
Dim channel_s() As Byte
<VBFixedArray(17)>
Dim channel_link_s() As Byte
<VBFixedArray(15, 15)>
Dim subchan_s(,) As Byte
Sub New(ByVal i As Boolean)
If i Then
ReDim channel_s(15)
ReDim channel_link_s(17)
ReDim subchan_s(15, 15)
End If
End Sub
End Structure
End Module
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim values As New BinCP42(True)
With values
.set_code = 256
.channel_sel_Low = 5
.channel_sel2_Low = 6
.name = "Test"
.channel_s(0) = 12
.channel_s(1) = 21
.channel_link_s(0) = 33
.subchan_s(0, 0) = 5
End With
'Datenstruktur speichern
SaveStructure2BinaryFile(values)
End
'und in neue Variable einlesen
Dim values2 As New BinCP42(True)
LoadBinaryFile2Structure(values2)
End Sub
Private Sub SaveStructure2BinaryFile(ByVal s As BinCP42)
Dim file As String = "k:\mwa\DATA.BIN"
If IO.File.Exists(file) Then IO.File.Delete(file)
Dim ch As Integer = FreeFile()
FileOpen(ch, file, OpenMode.Binary)
FilePut(ch, s)
FileClose(ch)
End Sub
Private Sub LoadBinaryFile2Structure(ByRef s As BinCP42)
Dim file As String = "K:\mwa\DATA.BIN"
If System.IO.File.Exists(file) Then
Dim ch As Integer = FreeFile()
FileOpen(ch, file, OpenMode.Binary)
FileGet(ch, s)
FileClose(ch)
End If
End Sub
|