Editieren von Dateien

  • VB.NET
  • .NET (FX) 4.0

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Editieren von Dateien

    Guten Morgen!

    Folgendes Problem:
    Ich soll ein Programm schreiben, dass eine sog. PRN-Datei einliest.
    Die Datei enthält ziemlich viel Text, ich muss sobald eine "section" beginnt die relativen Adressen zu absoluten Adressen (Hex) umrechnen.
    Das Problem ist, es können eine oder mehrere Sektionen in einer Datei sein und irgendwie kriege ich das nicht so recht hin.

    Beispiel für eine Sektion:

    Quellcode

    1. 337 B513 R section task1
    2. 338
    3. 339 B513 0080 ds 128 ;kommentar
    4. 340 00000080 tos equ *
    5. 341
    6. 342 ****************************************
    7. 343 * *
    8. 344 * Variablen *
    9. 345 * *
    10. 346 ****************************************
    11. 347
    12. 348 B593 0002 adc1 ds 2
    13. 349 B595 0002 adc2 ds 2
    14. 350 B597 0002 adc3 ds 2
    15. 351
    16. 352 B599 0002 timer1 ds 2
    17. 353 B59B 0002 timer2 ds 2
    18. 354 B59D 0002 timer3 ds 2
    19. 355 B59F 0002 timer4 ds 2
    20. 356 B5A1 0002 timer5 ds 2
    21. 357 B5A3 0002 timer6 ds 2
    22. 358 B5A5 0002 timer7 ds 2
    23. 359 B5A7 0002 timer8 ds 2
    24. 360 B5A9 0002 timer9 ds 2
    25. 361
    26. 362 B5AB 0002 tick ds 2 ;1ms Tick
    27. 363 B5AD 0002 stick ds 2 ;1s Tick
    28. 364 B5AF 0002 scomp ds 2
    29. 365 B5B1 0001 ready ds 1

    Das ist jetzt manuell von Hand berechnet, Berechnet werden muss bzw. errechnet werden muss der zweite Teil, also nach der Zeilennummerierung (so in der Datei vorhanden!) bspw. B5A9 etc.
    Beispiel einer weiteren Section (selbe Datei):

    Quellcode

    1. 373 100 R section task1_code
    2. 374
    3. 375 100 01 task1 db 1 ;Kommentar
    4. 376 101 00 db 0 ;Kommentar
    5. 377 102 0008 R dw Coldstart ;Kommentar
    6. 378 104 03E8 dw 1000 ;Kommentar
    7. 379 106 0080 R dw tos ;Kommentar


    Mein Code bisher:

    VB.NET-Quellcode

    1. For Each vItem As Task In Form1.vListe
    2. If Not vItem.Pfad = "" Then
    3. Using fr As New IO.StreamReader(vItem.Pfad)
    4. vItem.PRN = fr.ReadToEnd
    5. End Using
    6. Dim vBegan As Boolean = False
    7. Dim vEnded As Boolean = False
    8. Dim vSkip As Integer
    9. Dim vSkipBool As Boolean = False
    10. Dim vSplit() As String = vItem.PRN.Split(CChar(vbLf))
    11. Dim vSkipNow As Boolean = False
    12. For i As Integer = 0 To vSplit.Length - 1
    13. If vSplit(i).Contains("section " & vItem.Name.ToLower) Then
    14. vBegan = True
    15. vSkip = i
    16. vSkipBool = True
    17. End If
    18. If vBegan And Not vEnded Then
    19. If Not vSkip = i Then
    20. If vSplit(i).Contains(" section") Then
    21. vEnded = True
    22. Exit For
    23. End If
    24. End If
    25. If vSplit(i).Length > 10 Then
    26. Dim vStr0 As String = vSplit(i).Substring(7, 4)
    27. If vSplit(i).Contains("were") Then
    28. vSkipNow = True
    29. End If
    30. If Not vSplit(i) = " " And vSkipNow = False And Not vSplit(i).Contains("section") Then
    31. Dim vLet As Boolean = False
    32. If vStr0.Contains(" ") Then
    33. vStr0 = vSplit(i).Substring(6, 4)
    34. vLet = True
    35. End If
    36. Try
    37. Dim Result As String = String.Format("{0:X}", CInt("&H" & vStr0) + CInt("&H" & vItem.Begins))
    38. If vLet Then
    39. vSplit(i) = vSplit(i).Remove(6, 4)
    40. vSplit(i) = vSplit(i).Insert(6, Result)
    41. Else
    42. vSplit(i) = vSplit(i).Remove(7, 4)
    43. vSplit(i) = vSplit(i).Insert(7, Result)
    44. End If
    45. Catch ex As Exception
    46. End Try
    47. End If
    48. End If
    49. End If
    50. Next
    51. Using fw As New IO.StreamWriter(vItem.Pfad)
    52. For i As Integer = 0 To vSplit.Length - 1
    53. vSplit(i) = vSplit(i).Replace(vbLf, "")
    54. fw.WriteLine(vSplit(i))
    55. Next
    56. End Using
    57. ' Löschen der Variablen
    58. End If
    59. Next


    Das Ergebnis:
    Task1_Data wird gemacht, task1_code jedoch nicht.

    Hat jemand eine Idee, wie ich den Fehler beheben kann?
    Sitze jetzt seit zwei Tagen daran und komme keinen Schritt weiter und bin wirklich am verzweifeln...

    Vielen Dank,
    Musti
    @Neoner Was bedeuten die Spalten?
    Wo beginnen relative, wo absolute Adressen?
    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!
    Guten Morgen RodFromGermany!

    Beispiel:
    362 0098 0002 tick ds 2 ;1ms Tick

    0098 ist die relative Adresse und befindet sich in der section "task1_data".
    Mir liegt die Information vor, dass die Section task1_data bei der Adresse B513 beginnt. Nun muss ich die relative Adresse mit B513 addieren und und 0098 damit ersetzen.
    Das Ergebnis in diesem Fall wäre B5AB und würde wie folgt aussehen:
    362 B5AB 0002 tick ds 2 ;1ms Tick

    Ich hoffe das war etwas verständlicher :)

    VG,
    Neoner

    /E:
    Die Spalten beschreiben wohl irgendwie ein Assembler programm.
    Die ersten Zwei Zweilen der Datei besagen folgendes:

    Quellcode

    1. American Automation Assembler 6809 9.08.02 22 Dec 2014 11:00:31
    2. Options in effect:format list object errorfile uppercase

    Soweit ich weiß, werden bzw. sollen damit Motorsteuerungen angesteuert bzw. betrieben werden. So ganz genau weiß ich es aber nicht.

    Neoner schrieb:

    verständlicher
    Jou.
    Also zuerst: Schmeiß Deinen Spagetti-Code weg.
    Lies die einzelnen Zeilen ein und pack deren Inhalt in je eine Code-Instanz, die die volle Zeileninformation enthält, also Zeilennummer, relative Adresse, Länge, Inhalt.
    Adressen und so gib als Long ein, Inhalt als String.
    Diese Instanzen pack in eine List(Of T) in einer Sammelklasse.
    Dann gib dieser Sammelklasse Methoden zur Berechnung von Code-Abständen, indem sie die Längen der Code-Instanzen von a bis b aufsummiert.
    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!
    Hallo Rod,

    Ich habe nun eine Klasse erstellt, welche eben die Zeileninformationen enthält.
    Dann habe ich eine zweite Klasse erstellt, welche von List(of Klasse1) erbt.

    Was meinst du mit Methoden zur Berechnung von Code-Abständen?
    Ich muss die ursprüngliche Datei ja eben wieder genau so ausgeben - nur mit den "neuen" Adressen.

    VG

    Neoner schrieb:

    ausgeben
    Fang an mit dem Einlesen der Originaldaten, Aufdröseln der einzelnen Information und der Ausgabe, indem Du diese Information aus den Einzelteilen wieder zusammensetzt.
    Da sollte, ggf. bis auf Leefrzeichen, die identische Information drin stehen.
    Wenn das läuft, fängst Du an und addierst die Befehlslängen von (a+1) bis b. Das ist die relative Entfernung von a bis b, da musst Du wohl nur noch einen Offset drauf addieren und Du hast Deinen Wert.
    Teste das mit Papier und Bleistift.
    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!