Illegales Zeichen im Pfad

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    Illegales Zeichen im Pfad

    Hallo,
    Ich habe anscheinend ein illegales Zeichnen im Pfad, aber ich kann hab schon sogut wie alles untersucht aber ich kann da nix finden ||
    Das Programm soll eine Datei in ein Array einlesen wobei ein Teil des Dateipfades Variabel ist. Ich habe schon probiert den Pfad mir in einer MsgBox ausgeben zu lassen und da sieht er gut aus.
    Hier mein Code:

    Visual Basic-Quellcode

    1. #Region "Dimensionieren"
    2. Dim sek_array() As String
    3. sek_array = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\list.txt").Split(vbNewLine)
    4. Dim helper1 As Integer = sek_array.Length
    5. Dim sek_displayname(helper1) As String
    6. Dim sek_list(helper1) As String
    7. Dim sek_lockmode(helper1) As String
    8. Dim sek_purename(helper1) As String
    9. Dim sek_desc(helper1) As String
    10. #End Region
    11. #Region "Lade Sektionen"
    12. For i = sek_array.GetLowerBound(0) To sek_array.GetUpperBound(0)
    13. 'Die MsgBoxen sind hier nur zur Debugging zwecken um die Strings zu analysieren und zu schauen ob alles richtig läuft
    14. MsgBox("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\display_name.txt")
    15. MsgBox(My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\display_name.txt"))
    16. 'Lädt die Textdateien in die Arrays ein
    17. sek_displayname(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\display_name.txt")
    18. sek_list(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\list.txt")
    19. sek_lockmode(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\lockmode.txt")
    20. sek_purename(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\pure_name.txt")
    21. sek_desc(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\desc.txt")
    22. 'Die MsgBox ist hier nur eine Übergangslösung um zu erkennen ob alles Problemlos angezeigt wird
    23. Dim text As String = " Zusammenfassung von " & ControlChars.Quote & sek_array(i) & ControlChars.Quote & vbNewLine & "
    24. Ordername: " & sek_array(i) & "
    25. Anzeigename: " & sek_displayname(i) & "
    26. Originalname: " & sek_purename(i) & "
    27. Modus: " & sek_lockmode(i) & "
    28. Inhalte: " & vbNewLine & sek_list(i) & vbNewLine & vbNewLine & "
    29. Beschreibung: " & vbNewLine & sek_desc(i)
    30. MsgBox(text)
    31. Next i
    32. #End Region


    Der erste Durchgang läuft prima, aber wenn sich die i-Schleife wiederholt da sek_array 2 Einträge hat, bekommen ich die Fehlermeldung: System.ArgumentException: "Illegales Zeichen im Pfad."

    Details:
    System.ArgumentException ist aufgetreten.
    HResult=0x80070057
    Nachricht = Illegales Zeichen im Pfad.
    Quelle = mscorlib
    Stapelüberwachung:
    bei System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
    bei System.IO.Path.GetFileName(String path)
    bei System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
    bei System.IO.File.InternalReadAllText(String path, Encoding encoding, Boolean checkHost)
    bei System.IO.File.ReadAllText(String path)
    bei Microsoft.VisualBasic.MyServices.FileSystemProxy.ReadAllText(String file)
    bei MyLog.Form1.LoadFileSystem() in M:\Visual Studio\Projects\MyLog\MyLog\Form1.vb: Zeile75
    bei MyLog.Form1.VB$StateMachine_10_Form1_Shown.MoveNext() in M:\Visual Studio\Projects\MyLog\MyLog\Form1.vb: Zeile110

    Wobei der Fehler bei der Zeile mit der Msgbox auftaucht:

    Visual Basic-Quellcode

    1. MsgBox(My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\display_name.txt"))


    Wenn man diese Zeile entfernt dann springt der Fehler auf den nächsten Befehl mit " My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i) & "\config\display_name.txt") " im Code, also die darunter.

    Die MsgBox die davor nur den Dateipfad an sich ausgibt zeigt an: "C:\ProgramData\MyLog\Logs\Beispiele\config\display_name.txt"
    Wo ist der Fehler ?? ?(

    Zusätliche Infos:

    In "C:\ProgramData\MyLog\Logs\Beispiele\config\display_name.txt" steht:
    [-- Beispiele --]
    In "C:\ProgramData\MyLog\Logs\list.txt" steht:
    My Log
    Beispiele


    Videodemonstartion
    : 1drv.ms/v/s!AkSyWHBD0qRojqRqiMCJRTJlR-7fnw

    Schonmal Danke im Vorraus :D
    Laut des Videos (welches besser über die [Erweiterte Antwort] hätte hochgeladen werden sollen) sieht es so aus, als wäre in dem Pfad ein Zeilenumbruch.
    Lass Dir mal von Visual Studio ausgeben, ob in dem Pfad die Zeichen 13 oder 10 enthalten sind. In der Zeile des Absturzes einen Haltepunkt rein und wenn dann das Programm dort anhält, schau rein, was in dem Pfad konkret drinsteht. Ggf. auch ein nicht druckbares Zeichen. Erkennst Du daran, dass Du in den Pfadstring reinklickst, einzeln mit der Nach-Rechts-Pfeiltaste durch den String durchgehst und mitzählst. Bei nichtdruckbaren Zeichen, scheint es so, als ob der Cursor irgendwo an einzelnen Stellen hängenbleibt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    @VaporiZed So was denke ich auch.
    @VBnoob87 Machma

    VB.NET-Quellcode

    1. MsgBox(My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i).Trim() & "\config\display_name.txt")) ' Trim()

    und dies:

    VB.NET-Quellcode

    1. Dim txt = "bla" & Environment.NewLine ' hier Dein Pfad
    2. Dim index = txt.IndexOfAny(IO.Path.GetInvalidFileNameChars())
    3. If index >= 0 Then
    4. MessageBox.Show("gefunden: " & AscW(CChar(txt(index)).ToString))
    5. End If

    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!
    Okay danke schonmal.

    Hab mal den Code an den Anfang der i-Schleife eingebaut und bekomme 11mal die Meldung "10"

    Hab jetzt auch hinter alle sek_array´s .trim hintergeschrieben und es funktioniert jetzt besser als meine "provisorische" Lösung:

    Visual Basic-Quellcode

    1. For Each illegalChar As Char In IO.Path.GetInvalidFileNameChars
    2. sek_array(i) = sek_array(i).Replace(illegalChar, "")
    3. Next


    Mein Code sieht jetzt so aus:

    Visual Basic-Quellcode

    1. #Region "Sektionen"
    2. For i = sek_array.GetLowerBound(0) To sek_array.GetUpperBound(0)
    3. Dim txt = sek_array(i)
    4. Dim index = txt.IndexOfAny(IO.Path.GetInvalidFileNameChars())
    5. If index >= 0 Then
    6. MessageBox.Show("gefunden: " & AscW(CChar(txt(index)).ToString))
    7. End If
    8. sek_displayname(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i).Trim & "\config\display_name.txt")
    9. sek_list(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i).Trim & "\config\list.txt")
    10. sek_lockmode(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i).Trim & "\config\lockmode.txt")
    11. sek_purename(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i).Trim & "\config\pure_name.txt")
    12. sek_desc(i) = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\" & sek_array(i).Trim & "\config\desc.txt")
    13. ' Dim text As String = " Zusammenfassung von " & ControlChars.Quote & sek_array(i) & ControlChars.Quote & vbNewLine & "
    14. 'Ordername: " & sek_array(i) & "
    15. 'Anzeigename: " & sek_displayname(i) & "
    16. 'Originalname: " & sek_purename(i) & "
    17. 'Modus: " & sek_lockmode(i) & "
    18. 'Inhalte: " & vbNewLine & sek_list(i) & vbNewLine & vbNewLine & "
    19. 'Beschreibung: " & vbNewLine & sek_desc(i)
    20. ' MsgBox(text)
    21. Next i
    22. #End Region
    1. Statt die unguten zeichen codetechnisch zu entfernen, sollte ggf. dann doch die Quelle bearbeitet werden, falls möglich.
    2. Du hast jetzt Code gepostet. Nun die Frage: läuft's jetzt so, wie Du wolltest?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VBnoob87 Wenn Du nun den Verursacher des Fehlers gefunden hast, solltest Du die Ursache ausmerzen und aufklären, wo die Zeilentrennzeichen (LF=LineFeed) herkommen.
    Erzeuge Dir eine temporäre Variable, die den "sauberen" String enthält und verwende die statt n Mal sek_array(i).Trim zu verwenden.
    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!
    also ich bin mir nicht sicher warum aber ich glaube es liegt daran wie ich das sek_array befüllt habe:

    Visual Basic-Quellcode

    1. Dim sek_array() As String
    2. sek_array = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\list.txt").Split(vbNewLine)

    Ich habe eine Textdatei (list.txt) eingelesen und es nach jeder Neuen Zeile gesplittet. Das Textdokument ist ungefähr so aufgebaut

    Quellcode

    1. ​My Log
    2. ​Beispiele

    ​Und ich dachte eigentlich das durch das Splitten die neue Zeile nicht mit eingelesen wird aber ewinscheinend wird bei dem 2. Element am anfang noch die neue Zeile mit eingefügt.
    ​Hab zum Test einfach mal ne MsgBox die 2 Daten im Array auslesen lassen:
    1. Variable

    Quellcode

    1. ​My Log

    2.Variable

    Quellcode

    1. ​Beispiele


    Also denke ich mal das die Split Funktion nicht die Inhalte vor und nach dem Split-Punkt teilt sondern immer ab dem Punkt inkl. des Split-Punktes

    VBnoob87 schrieb:

    Also denke ich mal das die Split Funktion nicht die Inhalte vor und nach dem Split-Punkt teilt sondern immer ab dem Punkt inkl. des Split-Punktes

    Das ist falsch.

    Nur zur Info: Unter Windows wird ein manueller Zeilenumbruch meist durch zwei Zeichen gekennzeichnet, nämlich CR (Carriage Return, ASCII 13) und LF (Line Feed, ASCII 10). Es kommt auch, aber eher selten, vor, dass nur eines der beiden Zeichen verwendet wird. Unter Linux oder iOS sieht es wieder anders aus.

    Wenn du nach vbNewLine splittest, dann verwendest du nur ASCII 13 (also CR) als Trennzeichen, das nachfolgende LF (ASCII 10) bleibt dann am Anfang des Eintrags nach der Trennstelle zurück und führt bei Verwendung zu einem ungültigen Dateinamen. Also genau das, was du als Beobachtung in deinem letzten Beitrag beschrieben hast. Nur deine Schlussfolgerung daraus war falsch.

    Sorge also einfach dafür, dass nicht nur CR sondern auch LF zum Splitten deines Textes verwendet wird. Da du dann auch leere Strings (nämlich die Teile "zwischen" CR und LF) erhältst, solltest du - sinnvollerweise direkt beim Splitten - dafür sorgen, dass du keine leeren Einträge im Ergebnisarray zurückgegeben bekommst.

    ich würde mich nichtmal wundern, wenn es ein Sonderzeichen oder eine spezielle Funktion gibt, mit der man CR+LF grundsätzlich als "1 Zeilenumbruch" abhandeln kann. Aber da bin ich grad zu faul nach zu suchen.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Warum verwendest du nicht einfach:
    msdn.microsoft.com/de-de/library/s2tte0y1(v=vs.110).aspx

    GetLowerBound wird für alle Arrays immer 0 zurückgeben. GetUpperBound wird immer Length-1 zurückgeben. Verwende doch bitte diese. GetUpperBound gibt mMn nur Sinn für Mehrdimensionale Arrays. Und meist Versuch ich mehrdimensionale Arrays zu vermeiden, oftmals muss man das sowieso kapseln für irgendwelche Zusatzfunktionalitäten.

    Ansonsten, da du die Daten sowieso sequentiell abarbeitest, könntest du auch den StreamReader verwenden und die Zeilen einzeln einlesen und direkt abarbeiten, dürfte performanter sein und auch nicht komplizierter.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    @Arby Jou.

    VBnoob87 schrieb:

    VB.NET-Quellcode

    1. Dim sek_array() As String
    2. sek_array = My.Computer.FileSystem.ReadAllText("C:\ProgramData\MyLog\Logs\list.txt").Split(vbNewLine)
    Machst Du:

    VB.NET-Quellcode

    1. Dim sek_array() System.IO.File.ReadAllLines("C:\ProgramData\MyLog\Logs\list.txt")
    und feddich. :D
    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!

    Arby schrieb:

    ich würde mich nichtmal wundern, wenn es ein Sonderzeichen oder eine spezielle Funktion gibt, mit der man CR+LF grundsätzlich als "1 Zeilenumbruch" abhandeln kann.

    Exakt! :D
    Diese zum Beispiel: msdn.microsoft.com/en-us/library/tabh47cf(v=vs.110).aspx

    VB.NET-Quellcode

    1. Dim Parts As String() = "HalloZeilenumbruchWeltTrennzeichenTest".Split({"Zeilenumbruch", "Trennzeichen"}, StringSplitOptions.None)
    2. 'Parts = {"Hallo", "Welt", "Test"}
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Niko Ortner: Das ist klar. :D
    Ich meinte eher sowas wie blablubb.Split('\x'), wobei \x dann als Synonym für Escape-Zeichen für "Zeilenumbruch, egal ob CR oder LF oder beides" steht. Aber Rods Lösung, den Text gleich mit der Funktion ReadAllLines einzulesen ist natürlich besonders effektiv.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Falls es noch niemandem Aufgefallen ist, war ich der erste, der ReadAllLines empfohlen hat, nur über einen Link.

    Und besonders effektiv ist nicht ReadAllLines, sondern mit einem StreamReader und die Zeilen direkt verarbeiten....
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---