# Illegal char im Dateinamen



## MiMa (19. Jan 2018)

Beim einlesen von Dateien bin ich auf ungültige Zeichen gestossen.

```
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <*> at index 110: N:\Audio\test_02\This Summer's Gonna Hurt Like A Motherf****r.mp3
```
In der Konsole von Netbeans ist das ungültige Zeichen ein *.
In Explorer von Windows sieht der Dateiname so aus.

```
This Summer's Gonna Hurt Like A Motherf____R.mp3
```
Wie kann ich denn jetzt auf ein korrektes Zeichen prüfen.
Meine Idee wäre jetzt den Dateinamen als String Zeichen für Zeichen prüfen und die illegalen Zeichen einfach entfernen.
Dann ist immer noch die Frage wie prüfe ich das zeichen um die ungültigen heraus zu finden?
Ein weiterer Gedanke wäre alle Zeichen auf zu listen, welche im Dateinamen nicht enthalten sein dürfen. Diese dann im String gegenprüfen und dann entfernen.
Ob es einfacher geht, weis ich nicht?
Vielen Dank
Mi


----------



## MiMa (20. Jan 2018)

Erster Versuch

```
public static File pruefeDateiNamen(File datei) {
        String dateiname = datei.toString();
        // Liste ungültiger zeichen
        String ungueltigeZeichen = "?*<>,_+:;[]|}";
        dateiname = dateiname.replaceAll(ungueltigeZeichen, "");
        datei = new File(dateiname);
        return datei;
    } // pruefeDateiNamen
```
Fehlermeldung

```
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 0
[main] INFO Audiotest - Es wurden 1 Dateien gefunden
?*<>,_+:;[]|}
```


----------



## Thallius (20. Jan 2018)

Ein Unterstrich ist definitiv kein ungültiges Zeichen. DA würde ich eher auf das Abostroph tippen.


----------



## MiMa (20. Jan 2018)

Das habe ich hinzugefügt, aber funktioniert auch nicht. GLeiche Fehlermeldung wie o.a.?
Prüft die Methode replaceAll() jedes einzelne Zeichen in dem Dateinamen?
Oder muss ich die Zeichen in einer Schleife einzeln mit dem Dateinamen String vergleichen?


----------



## Thallius (20. Jan 2018)

warum gibst du nicht einfach den neuen dateinamen mal aus und schaust nach?


----------



## mrBrown (20. Jan 2018)

Der Stern ist das problematische Zeichen, steht doch auch in der Ausgabe...
Siehe auch hier: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx



MiMa hat gesagt.:


> Das habe ich hinzugefügt, aber funktioniert auch nicht. GLeiche Fehlermeldung wie o.a.?
> Prüft die Methode replaceAll() jedes einzelne Zeichen in dem Dateinamen?
> Oder muss ich die Zeichen in einer Schleife einzeln mit dem Dateinamen String vergleichen?


replaceAll nimmt einen regulären Ausdruck entgegen und ersetzt alles auf diesen matchende.

Für die problematischen Zeichen unter Windows müsste das sein:
	
	
	
	





```
"[<>:\"\\/|\\\\?*]"
```

Eckige Klammern für "einer aus", darin dann alle zutreffenden Zeichen.
'/' und '\' müssen in einem regulärem Ausdruck mit '\' escaped werden, weils in regulären Ausdrücken spezielle Zeichen sind. Danach müssen noch alle '\' und '"' mit einem '\' escaped werden, weils in Java-Strings spezielle Zeichen sind.


----------



## Thallius (20. Jan 2018)

mrBrown hat gesagt.:


> Der Stern ist das problematische Zeichen, steht doch auch in der Ausgabe...



und wo ist der Stern in

"This Summer's Gonna Hurt Like A Motherf____R.mp3"


----------



## mrBrown (20. Jan 2018)

Thallius hat gesagt.:


> und wo ist der Stern


In Index 110 in `N:\Audio\test_02\This Summer's Gonna Hurt Like A Motherf****r.mp3`


Seit wann ist denn `'` ein verbotenes Zeichen?


----------



## MiMa (20. Jan 2018)

Ich habe im Netz nachgeschlagen und auch gelesen das ein Hochkomma kein verbotenes Zeichen ist.
Allerdings habe ich auch nicht verstanden, das in der Fehlermeldung das "*" im Dateinamen angezeigt und auch das moniert wurde. Im Dateiexplorer von Windows und auch auf dem Mac sind unterstriche im Dateinamen zu sehen.
Daher muss es irgendwo im Programm ein Problem geben, aber ich ändere eigentlich nichts am Dateinamen?

Ich habe meine Methode jetzt angepasst:
Habe den Namen der Datei aus der datei extrahiert in String Dateiname und nachher wieder angehangen. Der String ungueltigeZeichen enthält die infos von mrBrown.

```
public static File pruefeDateiNamen(File datei) {
        String dateiname = datei.getName().toString();
        LOG.info("Dateiname : " + dateiname);
        // Liste ungültiger zeichen
        String ungueltigeZeichen = "[<>:\"\\/|\\\\?*]";
        dateiname = dateiname.replaceAll(ungueltigeZeichen, "");
        datei = new File(datei.getParentFile() + "/" + dateiname);
        return datei;
    } // pruefeDateiNamen
```
 Da es durch die Methode durchläuft, ist der Stern hier nicht im Dateinamen drin.
Die Audiodatei wird gelesen und auch die MP3 Tags darin.
Probleme gibt es erst wenn ich versuche eine Dateioperation  aus zu führen.

```
Files.move(quellDatei.toPath(), zielDatei.toPath());
```

Ausschnitt LOG:

```
[main] INFO  AudioKlasse - Gefundene - Datei - N:\Audio\test_01\1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  AudioKlasse - Es wurden 1 Dateien gefunden
[main] INFO  Dateioperationen - Dateiname - 1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  Dateioperationen - Datei wurde geprueft und geaendert in - N:\Audio\test_01\1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  Dateioperationen - Die Zieldatei ist - N:\Audio\test_02\1-23 This Summer's Gonna Hurt Like A Motherf****r.mp3
[main] INFO  Dateioperationen - Die Zieldatei ist nicht vorhanden und wird kopiert
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <*> at index 110: N:\Audio\test_02\1-23 This Summer's Gonna Hurt Like A Motherf****r.mp3
```
Ich mach mich auf der suche nach den Sternen im Dateinamen.


----------



## mrBrown (20. Jan 2018)

Wo kommt denn `zielDatei` her?


----------



## MiMa (20. Jan 2018)

Die zielDatei wird zusammengesetzt.
Die Dateien werden in anderen Verzeichnissen gespeichert.
Quelle ist hier   N:/Audio/test_01
Ziel ist hier       N:/Audio/test_02
Wenn es Alben oder Zusammenstellungen gibt, dann wird Tracknummer und CDNummer analysiert und auch mit berücksichtigt.

Hier mal ein anderes und vollständiges und umfangreiches LOG.

```
N:\SoundStation\test_01\1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  de.mima.Dateien.Dateioperationen - N:\SoundStation\test_01\1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  soundstation.SoundStation - Es wurden 1 Dateien gefunden
[main] INFO  de.mima.Dateien.Dateioperationen - Dateiname : 1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  de.mima.Dateien.Dateioperationen - geprüfte datei ist : N:\SoundStation\test_01\1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  soundstation.SoundParser - MP3 ID Tag Standard    Nein
[main] INFO  soundstation.SoundParser - MP3 ID Tag Version 3v1 JA
[main] INFO  soundstation.SoundParser - MP3 ID Tag Version 3v2 JA
[main] INFO  de.mima.Texte.Textoperationen - Der konvertierte String ist : Maroon 5
[main] INFO  de.mima.Texte.Textoperationen - Der konvertierte String ist : This Summer's Gonna Hurt Like A Motherf****r
[main] INFO  soundstation.SoundStation - Ausgabe gefundenen ID3-TAGs
[main] INFO  soundstation.SoundParser - ID-Tag 0 Maroon 5
[main] INFO  soundstation.SoundParser - ID-Tag 1 This Summer's Gonna Hurt Like A Motherf****r
[main] INFO  soundstation.SoundParser - ID-Tag 2 Pop
[main] INFO  soundstation.SoundParser - ID-Tag 3 null
[main] INFO  soundstation.SoundParser - ID-Tag 4 null
[main] INFO  soundstation.SoundParser - ID-Tag 5 -1
[main] INFO  soundstation.SoundParser - ID-Tag 6 Bravo Hits Vol. 90
[main] INFO  soundstation.SoundParser - ID-Tag 7 23/23
[main] INFO  soundstation.SoundParser - ID-Tag 8 1/2
[main] INFO  soundstation.SoundParser - ID-Tag 9 Bravo Hits
[main] INFO  soundstation.SoundParser - ID-Tag 10 2015
[main] INFO  soundstation.SoundParser - ID-Tag 11 220
[main] INFO  soundstation.SoundParser - ID-Tag 12 320
[main] INFO  soundstation.SoundParser - ID-Tag 13 44100
[main] INFO  soundstation.SoundParser - ID-Tag 14 -1
[main] INFO  soundstation.SoundParser - ID-Tag 15 Joint stereo
[main] INFO  soundstation.SoundParser - ID-Tag 16 N:\SoundStation\test_01\1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  soundstation.SoundParser - ID-Tag 17 null
[main] INFO  soundstation.SoundParser - ID-Tag 18 1443258270493
[main] INFO  soundstation.SoundParser - ID-Tag 19 1-23 This Summer's Gonna Hurt Like A Motherf____R.mp3
[main] INFO  soundstation.SoundParser - ID-Tag 20 null
[main] INFO  soundstation.SoundParser - Es wurde ein Eintrag für Album gefunden : Bravo Hits Vol. 90
[main] INFO  soundstation.SoundParser - Es wird nach einer Zusammenstellung gesucht
[main] INFO  soundstation.SoundParser - Es wurde eine Zusammenstellung gefunden : Bravo Hits
[main] INFO  soundstation.SoundStation - Das Ablageverzeichnis ist : Zusammenstellung
[main] INFO  soundstation.SoundParser - Das Trennzeichen ist in Tracks enthalten
[main] INFO  soundstation.SoundParser - Trennposition : 2
[main] INFO  soundstation.SoundParser - Getrennte Anfangs Zahl : 23
[main] INFO  soundstation.SoundParser - Getrennte End Zahl     : 23
[main] INFO  de.mima.Texte.Textoperationen - Fuellt eine String Zahl mit Nullen vor dem Wert auf
[main] INFO  de.mima.Texte.Textoperationen - zahlString : 23
[main] INFO  de.mima.Texte.Textoperationen - Zahllaenge : 2
[main] INFO  de.mima.Texte.Textoperationen - Wieviel ist auf zu fuellen : 0
[main] INFO  de.mima.Texte.Textoperationen - Zahl als String : 23
[main] INFO  soundstation.SoundParser - Anfangsnummer : 23
[main] INFO  soundstation.SoundParser - Endnummer     : 23
[main] INFO  soundstation.SoundParser - Das Trennzeichen ist in CD-Nummer enthalten
[main] INFO  soundstation.SoundParser - Trennposition : 1
[main] INFO  soundstation.SoundParser - Getrennte Anfangs Zahl : 1
[main] INFO  soundstation.SoundParser - Getrennte End Zahl     : 2
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <*> at index 110: N:\SoundStation\test_02\Musik\Zusammenstellung\Bravo Hits Vol. 90\1-23 This Summer's Gonna Hurt Like A Motherf****r.mp3
[main] INFO  soundstation.SoundParser - Anfangsnummer : 1
[main] INFO  soundstation.SoundParser - Endnummer     : 2
[main] INFO  soundstation.SoundParser - Die Ablage des Albums erfolgt über : Zusammenstellung
[main] INFO  soundstation.SoundParser - Das Album ist : Bravo Hits Vol. 90
[main] INFO  soundstation.SoundParser - Die Zieldatei ist : N:\SoundStation\test_02\Musik\Zusammenstellung\Bravo Hits Vol. 90\1-23 This Summer's Gonna Hurt Like A Motherf****r.mp3
[main] INFO  soundstation.SoundParser - Die Zieldatei ist nicht vorhanden
    at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
    at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
    at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
    at java.io.File.toPath(File.java:2234)
    at soundstation.SoundParser.ablageAudioDatei(SoundParser.java:243)
    at soundstation.SoundStation.main(SoundStation.java:106)
```
Irgendwo in den Textioperationen ist ein Problem bei der Konvertierung.
In der Klasse habe ich nur drei Methoden drin. Die einzige die infrage kommt ist die Methode in der Gross und Kleinschreibung umgeandelt wird.

```
/**
     * Wandelt alle Zeichen zu kleinbuchstaben und jeweils das Anfangszeichen Gross
     * @param zeichenkette <b>String</b> (DIE zeichenKETTE)
     * @return neueZeichenkette <b>String</b> (Die Zeichenkette)
     */
    public static String umwandelnGrossKlein(String zeichenkette) {
        // Variablendeklaration
        String neueZeichenkette = "";

        // String als Trennzeichen
        String[] isbnArray = zeichenkette.split(" ");
        for (int i = 0; i < isbnArray.length; i++) {
            isbnArray[i] = isbnArray[i].toLowerCase();
            isbnArray[i] = isbnArray[i].substring(0, 1).toUpperCase() + isbnArray[i].substring(1);
        }
        for (int j = 0; j < isbnArray.length; j++) {
            neueZeichenkette = neueZeichenkette + " " + isbnArray[j];
        }
        // Erstes Leerzeichen entfernen
        neueZeichenkette = neueZeichenkette.substring(1, neueZeichenkette.length());

        LOG.info("Der konvertierte String ist : " + neueZeichenkette);

        return neueZeichenkette;
    } // umwandelnGrossKlein
```


----------



## mrBrown (20. Jan 2018)

MiMa hat gesagt.:


> Hier mal ein anderes und vollständiges und umfangreiches LOG.


Das ist leider ziemlich nichtssagend, ohne den Code zu kennen 

Beim Umwandeln der Zeichenkette in passende Groß/Kleinschreibung kommt offensichtlich schon der String mit '*' raus.
Ob das was mit dem Problem zu tun hat - unmöglich zu sagen, ohne zu wissen was da passiert.


Wenn ich jetzt mal völlig ins blaue rate: Der Track-Name enthält '*', und den Tracknamen benutzt du für den neuen Dateinamen.


----------



## MiMa (20. Jan 2018)

Habe das Problem nun gefunden und behoben.
Das Problem lag weder am Dateinamen, noch an der Umwandlung von Gross und Kleinschreibung.
Der Grund warum der Dateinamen mit unterstriche war und nachher Sterne im Dateinamen geschrieben werden wollten lag darin, das in den MP3 id3v2 Tags der Titel mit den Sternchen enthalten war.
Da die zielDatei nicht aus dem ursprünglichen Dateinamen erstellt wird, sondern aus den id3 Tags konnte ich das Problem jetzt lösen. Ich prüfe jetzt auch den Titel vor dem Konvertieren in Gross und Kleinbuchstaben mit einer Methode auf ungültige Zeichen für Dateinamen.


----------



## mrBrown (20. Jan 2018)

Da hab ich ja sogar richtig geraten  




MiMa hat gesagt.:


> Ich prüfe jetzt auch den Titel vor dem Konvertieren in Gross und Kleinbuchstaben mit einer Methode auf ungültige Zeichen für Dateinamen.


Einfacher wird es vermutlich, wenn du nur vor dem Schreiben den Dateipfad validierst, nur an der Stelle ist es doch relevant?


----------



## MiMa (20. Jan 2018)

Hast recht, dann brauche ich das auch nur einmal an der richtigen Stelle.
In den Metadaten wird dadurch auch kein Problem verursacht deshalb könnte es dort so bleiben wie es ist.
Wenn jedoch ein Dateinamen erstellt wird, wird dieser immer geprüft.
Nochmals vielen Dank an alle.
Letztenendes hat mir der richtige Reguläre ausdruck sehr geholfen.
Vielen Dank


----------

