Anfängerfrage: .txt auslesen und schreiben - Fehlermeldung

  • VB.NET

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von egon.

    Anfängerfrage: .txt auslesen und schreiben - Fehlermeldung

    Hallo, VB2015
    nach längerer Abstinenz versuche ich mich wieder an einem kleinen Programm und möchte euch um Hilfe bitten.
    Das Programm soll je nach Button eine TXT-DAtei schreiben oder lesen. Leider kann ich mir den einen Fehler nicht erklären der auftritt, wenn ich die Buttons hintereinander betätige. (Fehler_1.png) Was ist die Ursache und wie kann man den Fehler beseitigen.

    Wie kann der Fall abgefangen werfden, wenn keine einzulesende Datei vorhanden ist.

    Grüße egon

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim writer As StreamWriter = File.CreateText("test01.txt")
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. For Each s As String In TextBox1.Lines
    5. writer.WriteLine(s)
    6. Next
    7. writer.Close()
    8. End Sub
    9. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    10. TextBox1.Text = File.ReadAllText("test02.txt")
    11. End Sub
    12. End Class

    Bilder
    • Fehler_1.png

      55,87 kB, 1.076×617, 154 mal angesehen
    Beim zweiten Klick vermutlich disposed, pack mal den streamwriter in einen using block in der sub; hier Bsp (bin nur mobil unterwegs daher msdn Auszug

    VB.NET-Quellcode

    1. Using outputFile As New StreamWriter(mydocpath & Convert.ToString("\WriteLines.txt"))
    2. For Each line As String In lines
    3. outputFile.WriteLine(line)
    4. Next
    5. End Using

    Gruß Hannes
    In meinem Ursprungsbeitrag habe ich vergessen zu schreiben, worauf alles hinauslaufen soll.
    Eine alte Plotter-Datei soll eingelesen und verändert und unter einem neuen Namen abgespeichert werden. Vor mehreren Jahren habe ich dieses Problem schon mal mit der Programmiersprache Purebasic gelöst. Nun möchte ich dieses alte Programm nach Visual Basic portieren und erweitern. Damals habe ich die Datei in einen String eingelesen und dann mit Stringoperationen den Rest erledigt.
    Ob ich mit StreamWriter mich meinem Problem überhaupt nähern kann, kann ich auch noch nicht veurteilen.
    Hier ein Ausschnitt aus der Plotterdatei mit der Dateiendung *.plt:

    VB.NET-Quellcode

    1. PU;SP1;LT;;PU;PA550,7055;PD;PA676,7253;PU;PA622,7168;PD;PA694,7168,622,7055;PU;PA622,6999;PD;PA730,7168,802,7168,730,7055,658,7055;SP1;SR1.042,1.953;LT;;PU;PA1270,900;PD;PA8490,900,8490,6547,1270,6547,1270,900;LT;PU;SP1;LT;;PU;PA1126,279;LB#RES BW 1.LB0/;

    Benutze die statische Klasse File und dessen Member; exemplarisch: File.AppendAllText(path, content), dieser öffnet, schreibt in die Datei und schließt diesen abschließend.

    Edit: Habe deinen Edit irgendwie nicht gesehen oder nicht sehen wollen,
    du kannst die Plotter Datei mit File.ReadAllText() einer Variable allozieren ,StringOperationen anwenden, und anschließend die Datei mit File.WriteAllText aktualisieren.
    Und Gott alleine weiß alles am allerbesten und besser.

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

    Siehe Edit;

    C#-Quellcode

    1. string _plotterFile = File.ReadAllText("pfad");
    2. //String-Operationen
    3. _plotterFile = _plotterFile.Replace("", "");
    4. File.WriteAllText("pfad", _plotterFile);

    Und Gott alleine weiß alles am allerbesten und besser.
    @egon Schmeiß den Writer raus, den solltest Du nicht in der Klasse, sondern stets in einer Prozedur instanziieren.
    Da Du die Prozedur File.ReadAllText() gefunden hast, frage ich mich, warum Du File.WriteAllLines() nicht gefunden hast. :/
    @hans im glück Du hast da 4 Zeilen zu viel. ;)

    VB.NET-Quellcode

    1. File.WriteAllLines("test01.txt", TextBox1.Lines)

    egon Welche Endung die Datei hat ist belanglos.
    Welches Format muss diese Datei haben?
    Dürfen da Zeilenschaltungen drin sein?
    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!
    Die Datei bestecht aus ASCII-Zeichen. Ich habe sie als Bild angehängt. Die Zeilen werden mit einem CR/LF oder CR beendet. Weiterhin gehe ich davon aus, dass es keine Rolle spielt, ob die Zeile mit CR/LF oder CR beendet wird.
    Ein weitere Zeilenumbruch ist nicht vorgesehen. Es kann also sein, dass eine Zeile recht lang wird (Siehe Zeile 4).
    Lässt man sich diese Datei mit einem externen Programm anzeigen, ergibt sich das angehängte Bild.
    Bilder
    • GPIB_18 (1)_neu.gif

      10,24 kB, 640×480, 120 mal angesehen
    • PLT-Beispieldatei als Bild.png

      138,35 kB, 1.148×1.148, 139 mal angesehen
    @egon Wenn das ASCII-Zeichen sind, solltest Du auch ASCII lesen und schreiben, sonst kommt UNICODE auf die Platte und damit hat Dein CAD (oder so)-Programm ggf. Schwierigkeiten.
    Hinterfrage zunächst den konkreten Zeichensatz und wende ihn dann so an:

    VB.NET-Quellcode

    1. TextBox1.Text = IO.File.ReadAllText("test02.txt", System.Text.Encoding.ASCII)
    2. ' ...
    3. IO.File.WriteAllLines("test01.txt", TextBox1.Lines, System.Text.Encoding.ASCII)
    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!
    @egon Entweder es gibt eine Testfunktion, die alle Zeichen sendet oder Du treibst das Handbuch auf, da sollte das drin stehen.
    Wenn Die die Firma bekannt ist, kannst Du ja mal anrufen.
    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!
    Nun habe ich verschiedene Möglichkeiten zum Öffnen und Schließen von TXT-Dateien ausprobiert. Die beiden Dialoge zum Speichern und Öffnen der Dateien habe ich aus einem Buch von Walter Dobrenz entnommen.
    Könnt ihr euch bitte mal den Code ansehen. Habe ich irgendwelche Überprüfungen vergessen. Ist alles wasserfest?
    Grüße Jörn


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Public Class Form1
    4. Private _plotterFile As String
    5. Private pfad As String
    6. Private s As String
    7. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    8. With OpenFileDialog1
    9. .DefaultExt = "txt"
    10. ' Die(Filterzeichenfolge)
    11. .Filter = "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*"
    12. ' Warnung, wenn der Namen einer nicht vorhandenen Datei eingegeben wird:
    13. .CheckFileExists = True
    14. 'Das(Anfangsverzeichnis)
    15. .InitialDirectory = Application.ExecutablePath
    16. ' Beschriftung der Titelleiste des Dialogs:
    17. .Title = "Bitte öffnen Sie eine Textdatei!"
    18. End With
    19. ' Speichern-Dialog:
    20. With SaveFileDialog1
    21. .DefaultExt = "txt"
    22. ' standardmäßig eingetragener Dateiname:
    23. .FileName = "Beispiel.txt"
    24. ' Automatisches Anhängen der DefaultExt, falls diese weggelassen wird:
    25. .AddExtension = True
    26. ' Warnung, wenn bereits eine gleichnamige Datei vorhanden ist:
    27. .OverwritePrompt = True
    28. ' überprüfen, ob Dateiname erlaubte Zeichen enthält:
    29. .ValidateNames = True
    30. ' Weitere(Einstellungen)
    31. .Filter = "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*"
    32. .InitialDirectory = Application.ExecutablePath
    33. .Title = "Bitte speichern Sie die Textdatei!"
    34. End With
    35. End Sub
    36. Private Sub Button4_Click(sender As Object, e As EventArgs) Handles But_txt_direkt_einlesen.Click
    37. If My.Computer.FileSystem.FileExists("test02.txt") Then
    38. _plotterFile = IO.File.ReadAllText("test02.txt", System.Text.Encoding.ASCII)
    39. TextBox1.Text = _plotterFile 'Dieser Umweg wird gewählt um mit STRING zu experimentieren
    40. Else
    41. TextBox1.Text = "Datei nicht vorhanden"
    42. End If
    43. End Sub
    44. Private Sub Button6_Click(sender As Object, e As EventArgs) Handles But_txt_direkt_speichern.Click
    45. IO.File.WriteAllLines("test_speichern.txt", TextBox1.Lines, System.Text.Encoding.ASCII)
    46. End Sub
    47. Private Sub But_txt_Dialog_einlesen_Click(sender As Object, e As EventArgs) Handles But_txt_Dialog_einlesen.Click
    48. If OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
    49. pfad = OpenFileDialog1.FileName
    50. TextBox1.Text = String.Empty
    51. Try
    52. TextBox1.Text = File.ReadAllText(pfad)
    53. Catch
    54. End Try
    55. ' Dateipfad in der Titelleiste des Formulars anzeigen:
    56. Me.Text = pfad
    57. End If
    58. End Sub
    59. Private Sub But_txt_dialog_speichern_Click(sender As Object, e As EventArgs) Handles But_txt_dialog_speichern.Click
    60. If SaveFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
    61. pfad = SaveFileDialog1.FileName
    62. File.WriteAllText(pfad, TextBox1.Text)
    63. Me.Text = pfad
    64. End If
    65. End Sub
    66. Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click
    67. s = TextBox1.Text
    68. TextBox1.Text = s.Replace("1", "0")
    69. End Sub
    70. End Class
    Bilder
    • Dialog.png

      6,49 kB, 578×320, 88 mal angesehen

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

    Die Variablen solltest du alle Methoden-lokal deklarieren - alle 3.
    Als Klassenvariable sind die nicht erforderlich, und unnötige Klassenvariablen stellen schlechte Kapselung dar.

    Eine gute Übung wäre sicher auch, wenn du mit Instanzen der FileInfo-Klasse arbeiten tätest.
    Aber wie gesagt nur zur Übung, ihren Vorzug spielen FileInfo-Objekte erst aus, wenn sie mehrfach zugegriffen werden, bzw. mehr Information von ihnen abgerufen wird.
    Aber du testest ja nur FileExists, und das kann in diesem Fall My.Computer auch.
    @φConst: Ich würde statt ReadAllText, ReadAllLines verwenden und das Array der Eigenschaft .Lines der TextBox übergeben.

    Warum würdest du das machen?

    @ErfinderDesRades:
    "Die Variablen solltest du alle Methoden-lokal deklarieren - alle 3."
    Das leuchtetein. Die drei Variablen werden in die SUB reingezogen und mit DIM deklariert.

    "Eine gute Übung wäre sicher auch, wenn du mit Instanzen der FileInfo-Klasse arbeiten tätest. Aber wie gesagt nur zur Übung, ihren Vorzug spielen FileInfo-Objekte erst aus, wenn sie mehrfach zugegriffen werden, bzw. mehr Information von ihnen abgerufen wird.
    Aber du testest ja nur FileExists, und das kann in diesem Fall My.Computer auch. "
    Das mit den Instanzen der FileInfo-Klasse habe ich nocht nicht verstanden. Könntest du mir das bitte ausführlicher erklären? Was ist es sinnvoll mehrfach auf FileInfo-Objekte zuzugreifen?
    @egon ReadAllText vs. ReadAllLines ist zunächst kontextbezogen, also abhängig vom Text selbst, insbesondere von den verwendeten Zeilenumbruchzeichen. Ansonsten ist das Geschmackssache.
    FileInfo-Objekte sind dann sinnvoll, wenn Du primär mit den Dateien selbst, nicht aber mit ihren Inhalten arbeitest: Auflisten, sortieren (Name, Größe, Zeit), umbenennen, kopieren usw.
    ====
    Nicht mit My.Computer..., sondern mit System.IO.File.Exists() testen, ob eine Datei existiert. ;)
    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!

    egon schrieb:

    Das mit den Instanzen der FileInfo-Klasse habe ich nocht nicht verstanden. Könntest du mir das bitte ausführlicher erklären? Was ist es sinnvoll mehrfach auf FileInfo-Objekte zuzugreifen?

    VB.NET-Quellcode

    1. Dim fiInput = New FileInfo("c:\Temp\SourceFile1.txt") ' Es ist das Schlüsselwort New, was eine neue ('new') Instanz einer Klasse erstellt (alias 'Objekt').
    2. If Not fiInput.Exists Then
    3. MessageBox.Show(String.Format("Die Datei '{0}' existiert nicht", fiInput.FullName))
    4. Else
    5. MessageBox.Show(String.Format("In die Datei '{0}' wurde am {1} letztmalig geschrieben", fiInput.Name, fiInput.LastWriteTime.Date))
    6. End If
    Hier wird aus einem String ein FileInfo gebildet, und dann werden 4 (Datei-)Informationen desselben Objekts verwendet:
    1. Exists
    2. FullName
    3. Name
    4. LastWriteTime
    Was diese FileInfo-Eigenschaften im Einzelnen bedeuten muss ich nichtmal erklären (oder gar hinzukommentieren).
    Denn die FileInfo-Klasse ist vorbildlich designed, und durch Benamung und Benamung ihrer Properties vollständig selbsterklärend -
    Nomen est Omen!


    Wie gesagt: Eine Übung in OOP, bei der Dinge vorkommen wie: Instanzierung, Datentyp, Unterscheidung von Objekt und Klasse, Strukturierung von Information.
    Wenn du dir nu FileInfo und seine Verwandten auch noch im ObjectBrowser anguckst - kann gut sein, du magst anders gar nimmer programmieren ;)
    guggemol auch Film: VisualStudio nutzen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Danke für die Antworten. Ich werde es heute noch ausprobieren.

    Dann hätte ich noch eine Frage.
    Wie kann man ein Batch-File ausführen, welches weitere Programme aufruft, die eigenständig Messungen durchführen und dann warten, bis sie automatisch beendet sind.

    Mein Versuch hat nicht funktioniert:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim proc As Process = New Process()
    3. proc.StartInfo.FileName = "D:\Programme\KE5FX alt\GPIB\test teil2 001.bat"
    4. proc.WaitForExit()
    5. MessageBox.Show("Fertig")
    6. End Sub


    Hier noch das Batchfile zur Info D:\Programme\KE5FX alt\GPIB\test teil2 001.bat

    VB.NET-Quellcode

    1. @echo off
    2. talk 18 "SNGLS"
    3. talk 18 "TS"
    4. talk 18 "MKPK HI"
    5. binquery 18 "MKA?" Marker_Amplitude.txt
    6. binquery 18 "MKF?" Marker_Frequenz.txt
    7. binquery 18 "TDF P TRA?" trace_TDF_p.txt
    8. query 18 "PLOT 0,0,10000,8000;" >test01.plt
    9. 7470 test01.plt

    Die Programm die aufgerufen werden heißen "talk.exe", binquery.exe" und "7470.exe". Sie kümmern sich um den sehr betagten GPIB Bus zur Ansteuerung des Messgerätes. Als Rückanwort bekomme ich einzelne TXT-Files, die dann später von meinem Programm eingelesen und ausgewertet werden sollen. Es wäre schön, wenn es mit dem Batch-File klappt, da man dann später die Messroutine anpassen könnte ohne dass die ganze Software neu kompiliert werden müsste.

    egon schrieb:

    Es wäre schön, wenn es mit dem Batch-File klappt
    Das ist eine sehr wage Aussage.
    Da musst Du schon eine sehr präzise Aufgabenstellung / Problembeschreibung schreiben, denn der Output der aufgerufenen Programme wird sicher iwann auf der Festplatte stehen, aber eine Batch kann nicht warten, bis eine Datei da ist.
    Es sieht mir so aus, als wolltest Du so was wie einen Makrointerpreter haben, auch das ist so einfach nicht.
    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!