Binärdaten auslesen mit VB.NET

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Eierlein.

    Binärdaten auslesen mit VB.NET

    Neu

    Hallo zusammen,

    ich bin zurzeit dabei ein altes VB6-Programm in VB.NET umzuschreiben, zu verbessern, Features hinzuzufügen, usw.
    Nun hänge ich an einer Datei, die in VB6 gespeichert wurde und nun in VB.NET geöffnet und gelesen werden soll. Die ersten und die letzten Zeilen kann ich problemlos auslesen. Zwischendrin habe ich jedoch einen Datensatz, bei dem es mit dem Format mal gar nicht stimmt.

    So wird's in VB6 gespeichert:

    Visual Basic-Quellcode

    1. Dim FileNum As Integer
    2. Dim N As Integer
    3. Dim Wert As Meßkoordinaten
    4. Dim Wert_Durch As Durchmesserwerte
    5. Private Sub Speichern_Click()
    6. '...
    7. MousePointer = 11
    8. Open Dateiname For Random As FileNum
    9. Call Save_Berechnung
    10. Close #FileNum
    11. MousePointer = 0
    12. '...
    13. End Sub
    14. Private Sub Save_Berechnung()
    15. Put #FileNum, 1, Dateikennung
    16. Put #FileNum, 2, Messdatum
    17. '....
    18. For i = 1 To Anzahl_Koordinaten_RAM3
    19. N = N + 1
    20. Wert.Punkt = Punkt_Nr(i)
    21. Wert.X_Wert = X_Koordinate(i) 'diese Werte kann ich nicht auslesen
    22. Wert.Y_Wert = Y_Koordinate(i)
    23. Wert.Z_Wert = Z_Koordinate(i)
    24. Put #FileNum, N, Wert
    25. Next i
    26. For i = 1 To Anzahl_Stationen
    27. N = N + 1
    28. Wert_Durch.Wert1 = Durchmesser_L_R(i) 'diese jedoch schon
    29. Wert_Durch.Wert2 = Durchmesser_R_R(i)
    30. Wert_Durch.Wert3 = Durchmesser_LR(i)
    31. Wert_Durch.Wert4 = Höhenkorrektur(i)
    32. Wert_Durch.Wert5 = Relativbewegung(i)
    33. Put #FileNum, N, Wert_Durch
    34. Next i
    35. '....
    36. End Sub


    So sind Meßkoordinaten und Durchmesserwerte definiert:

    Visual Basic-Quellcode

    1. Type Meßkoordinaten
    2. Punkt As Integer
    3. X_Wert As Double
    4. Y_Wert As Double
    5. Z_Wert As Double
    6. End Type
    7. Type Durchmesserwerte
    8. Wert1 As Single
    9. Wert2 As Single
    10. Wert3 As Single
    11. Wert4 As Single
    12. Wert5 As Single
    13. End Type


    So sieht ein Datensatz von den Koordinaten aus:
    30 200000 200000 100000
    31 161140,5 206518 99899,6
    32 170700,6 202696,2 99726,9
    usw.

    So sieht ein Datensatz von den Durchmessern aus:
    1993,9 1990,7 6411,5 -5,546 34,852
    usw.


    Und nun das ganz in VB.NET

    VB.NET-Quellcode

    1. Dim Datei As String = Datei_Pfad & "\" & Dateiname
    2. fileNum = FreeFile()
    3. FileOpen(fileNum, Datei, OpenMode.Random)
    4. Call Load_PSC()
    5. FileClose(fileNum)
    6. Sub Load_PSC()
    7. Dim N As Integer
    8. FileGet(fileNum, Dateikennung, 1)
    9. FileGet(fileNum, Messdatum, 2)
    10. For i = 1 To Anzahl_Koordinaten_RAM3
    11. N = N + 1
    12. FileGet(fileNum, Wert, N)
    13. Punkt_Nr(i) = Wert.Punkt
    14. X_Koordinate(i) = Wert.X_Wert 'diese Werte stimmen nicht
    15. Y_Koordinate(i) = Wert.Y_Wert
    16. Z_Koordinate(i) = Wert.Z_Wert
    17. Next
    18. For i = 1 To Anzahl_Stationen
    19. N = N + 1
    20. FileGet(fileNum, Wert_Durch, N)
    21. Durchmesser_L_R(i) = Wert_Durch.Wert1 'diese hingegen schon
    22. Durchmesser_R_R(i) = Wert_Durch.Wert2
    23. Durchmesser_LR(i) = Wert_Durch.Wert3
    24. Höhenkorrektur(i) = Wert_Durch.Wert4
    25. Relativbewegung(i) = Wert_Durch.Wert5
    26. Next
    27. '...
    28. End Sub



    So sehen dann die guten, alten Koordinaten aus (Punktnr, x-Wert, y-Wert, z-Wert):
    30 3.53278645668721E-310 3.53278645668721E-310 3.52939126342166E-310
    31 3.53177986860812E-310 -2.41356463899063E-185 3.52938606204523E-310
    -858980320 -2.41355850579437E-185 1.89119455317217E+185 3.52937711505615E-310
    -1717960671 4.68038614173845E-62 4.68039675961272E-62 3.52937523965949E-310

    Und so die Durchmesser (alles richtig):
    1993.9 1990.7 6411.5 -5.54698 34.85271
    1986.8 2000.6 6633.2 0 0
    1984.5 1971 6499.8 0 0


    Wo liegt das Problem? Ich versteh es nicht wirklich ?( . Ich hoffe ihr könnt mir weiterhelfen.

    Neu

    Ich hab ganz ehrlich gesagt keinen Plan was du vor hast,
    weil es chronologisch absolut keinen Sinn ergibt, was du
    nun genau machen willst.

    Mach dir zuerst mal eine richtige detaillierte Beschreibung,
    was dein Vorhaben überhaupt schlussendlich erfüllen soll.
    Plane dir einen genauen Ablauf wie du das programmiertechnisch
    umsetzen willst.

    Informiere dich gründlich über die Unterschiede zweischen VB6
    und VB.Net. Nimm dazu das Internet und die Microsoft-Plattform.
    Eventuell bekommst du hier im Forum auch Unterstützung zum
    Thema VB6.

    Gehe Vb.net-Spezifisch vor, und vergiss am Besten Vb6.
    D.h. nicht irgendwelcher Code von Vb6 kopieren und in Vb.Net
    kopieren, sondern von grundauf solide Vb.Net technisch dein
    Vorhaben umsetzen.

    **********************************************************
    **********************************************************

    Da würde ich ungefähr so vorgehen
    (Man könnte auch Strukturen nehmen)
    - Klasse Messkoordinaten erstellen
    - Klasse Durchmesserwerte erstellen

    2 Methoden für die Files
    - SetFile(filename)
    - GetFile(filename)
    >> Wichtig: Die Dateien nicht offen lassen, wenn es nicht unbedingt sein muss

    2 Methoden für die Konvertierung
    - Convert Messkoordinaten
    - Convert Durchmesserwerte

    Und nun kannst du damit machen was du willst.

    Freundliche Grüsse

    exc-jdbi

    Neu

    @tina83 Die Daten sehen aber eher nach Text-Daten aus.
    Also:
    Mach das Einlesen neu.
    Lies die Datei zeilenweise ein: IO.File.ReadAllLines(...)
    Mit
    For Each line As String in ALL_LINES_ARRAY
    oder
    For i = 0 To ALL_LINES_ARRAY.Length - 1
    iterierst Du Dich durch das Array durch.
    Dim parts = line.Spliot(" "c) zerlegt die Zeile in ihre Bestandteile
    und dann

    VB.NET-Quellcode

    1. Punkt_Nr(i) = parts(0)
    2. X_Koordinate(i) = parts(1)
    3. Y_Koordinate(i) = parts(2)
    4. Z_Koordinate(i) = parts(3)

    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).
    VB-Fragen über PN / Konversation werden ignoriert!

    Neu

    IO.File.ReadAllLines
    funktioniert doch nur mit ASCII-Formaten? Nicht aber mit binär-Dateien - soweit ich weiß

    mit IO.File.ReadAllLines bekomme ich die Datei nicht so geöffnet, dass ich diese lesen kann. Es sind nur kryptische Zeichen drin

    ich vermute um

    VB.NET-Quellcode

    1. fileNum = FreeFile()
    2. FileOpen(fileNum, Datei, OpenMode.Random)
    3. Call Load_PSC(Datei)
    4. FileClose(fileNum)

    werde ich nicht drumrum kommen, oder?

    Neu

    @tina83 Poste mal bitte diese Datei, in eine ZIP verpackt.
    Erweiterte Antwort => Dateianhänge => Hochladen.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!

    Neu

    @tina83 OK, das sind Binärdaten.
    Poste mal bitte den Code, mit dem diese Daten erzeugt wurden.
    Steht oben, ich sehs mir mal an.
    Wahrscheinlich sind es nur die Dateitypen.

    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).
    VB-Fragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Neu

    @tina83 Also dies:
    Basic 16 Bit oder Basic 32 Bit?
    Dateikennung ist nicht deklariert, das dürfte wohl ein Integer sein (Short oder Integer)
    Messdatum wenn das mit Now ermittelt wurde, ist es ggf. ein Double. Die Vorkommastellen sind das Datum, die Nachkommastellen die Zeit.
    Den Rest bekommst Du so hin.
    Arbeite in jedem Falle mit Option Strict On :!:
    Wenn Du das Format dann lesen kannst, arbeite mit einem BinaryReader!
    =====
    Du musst Dir die DAtei unbedingt mit einem Hex-Viewer ansehen, damit Du verfolgen kannst, was da losgeht.
    Das Auslesen von Basic-Strings und der Strukturen hab ich mal implementiert.
    Du musst natürlich noch das Drumherum basteln.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Text
    3. Public Class Form1
    4. Structure Meßkoordinaten
    5. Public Punkt As Integer
    6. Public X_Wert As Double
    7. Public Y_Wert As Double
    8. Public Z_Wert As Double
    9. End Structure
    10. Structure Durchmesserwerte
    11. Public Wert1 As Single
    12. Public Wert2 As Single
    13. Public Wert3 As Single
    14. Public Wert4 As Single
    15. Public Wert5 As Single
    16. End Structure
    17. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    18. Dim value As Short
    19. Dim Dateikennung As String
    20. Dim Messdatum As Double
    21. Dim bytes() As Byte
    22. Dim koord As Meßkoordinaten
    23. Dim durchm As Durchmesserwerte
    24. Dim path = "F:\Binärdatei\MESS_H02\MESS_H02.PSC"
    25. Dim str = New IO.FileStream(path, FileMode.Open)
    26. Using br = New BinaryReader(str)
    27. value = br.ReadInt16()
    28. bytes = br.ReadBytes(value)
    29. Messdatum = br.ReadDouble()
    30. koord = ReadKoordinaten(br)
    31. durchm = ReadDurchmesser(br)
    32. End Using
    33. Dateikennung = Encoding.Default.GetString(bytes)
    34. Stop
    35. End Sub
    36. Private Function ReadKoordinaten(ByVal br As BinaryReader) As Meßkoordinaten
    37. Dim koord As Meßkoordinaten
    38. koord.Punkt = br.ReadInt32()
    39. koord.X_Wert = br.ReadDouble()
    40. koord.Y_Wert = br.ReadDouble()
    41. koord.Z_Wert = br.ReadDouble()
    42. Return koord
    43. End Function
    44. Private Function ReadDurchmesser(ByVal br As BinaryReader) As Durchmesserwerte
    45. Dim durchm As Durchmesserwerte
    46. durchm.Wert1 = br.ReadSingle()
    47. durchm.Wert2 = br.ReadSingle()
    48. durchm.Wert3 = br.ReadSingle()
    49. durchm.Wert4 = br.ReadSingle()
    50. durchm.Wert4 = br.ReadSingle()
    51. End Function
    52. End Class

    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).
    VB-Fragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „RodFromGermany“ ()

    Neu

    Visual Basic-Quellcode

    1. Type Meßkoordinaten
    2. Punkt As Integer -----> Short oder Int16
    3. X_Wert As Double
    4. Y_Wert As Double
    5. Z_Wert As Double
    6. End Type


    Ein VB.net Integer entspricht einem VB6 Long
    Ein VB6 Integer muss bei VB.net als Short oder Int16 deklariert werden

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Eierlein“ ()