# Konvertieren zu gültigen Dateinamen



## TypusMensch (16. Aug 2008)

Folgendes Problem:

Ich habe aus einer INI einen Namen herausgelesen. Dieser Name soll nun Bestandteil eines neuangelegten Verzeichnisses sein (File.mkdir()). Das klappt wunderbar. Leider streikt er beim Anlegen bzw. beim späteren Kopieren von Dateien in das Verzeichnis oftmals, dass das Verzeichnis nicht vorhanden ist, oder direkt folgende Meldung:
"Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch"

Fakt ist, dass oftmals Zeichen wie Doppelpunkt, Fragezeichen, Hochkommas usw. in den Namen in der Ini stehen, welche ja nicht als Verzeichnisse gültig sind. Da liegt das Problem. Wie kann ich explizit diese Zeichen herausfiltern? Das ganze soll am Ende plattformunabhängig sein.

Vielleicht jemand eine Idee?

Habs jetzt erstmal so gelöst... vielleicht hat aber jemand einen besseren Einfall:


```
name.replaceAll("\\", "");
    name.replaceAll("/", "");
    name.replaceAll("*", "");
    name.replaceAll("?", "");
    name.replaceAll("\"", "");
    name.replaceAll("<", "");
    name.replaceAll(">", "");
    name.replaceAll("|", "");
```


----------



## dayaftereh (16. Aug 2008)

Hey vielicht hilft ja das, so kannst du bestimmte zeichen ersetzen zu den die du haben willst


```
String str = "Hallo|ich|was|mach";
		str = str.replace("|", " ");
```

Weiß ja nicht ob das,dass ist was du suchst ^^


----------



## musiKk (16. Aug 2008)

Wow. Das ist ja auch ueberhaupt nicht das, was der OP schon hat...

Fakt ist, dass die Geschichte mit den zulaessigen Zeichen im Dateinamen am Dateisystem liegt und die sind was Sonderzeichen angeht sehr unterschiedlich. Am besten schaust du mal hier vorbei und suchst dir den kleinsten gemeinsamen Nenner aller Plattformen, die du unterstuetzen willst.


----------



## TypusMensch (16. Aug 2008)

LOL.

Naja aber mit dieser oben genannten Methode kommt häufig ein:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1



Am besten ich lasse nur A-Z, 0-9 und Leerzeichen zu. Das würde schon reichen, wenn es denn funktioneren würden...


----------



## musiKk (16. Aug 2008)

Da muesstest du mal ein konkretes Beispiel liefern.


----------



## Guest (16. Aug 2008)

Muss es denn unbedingtein spezieller Name sein oder tut es vielleicht auch eine fortlaufende Nummerierung oder ein timestamp.toString?


----------



## TypusMensch (16. Aug 2008)

Hat sich soeben erledigt. Hab grad in den JavaDocs gelesen, dass sich beim ersten Parameter um Regex (Reguläre Ausdrücke) handelt. Folgendes funktioniert jetzt bei mir:


```
private String convertToFileSystemChar(String name) {
    name.replaceAll("[^a-zA-Z0-9 ]", "");
    return name;
}
```

Edit: Muss ein konkreter Name sein.


----------



## TypusMensch (16. Aug 2008)

Gut, es war ja auch schon spät. Verdammt. 

Ein Aufruf von:
System.out.println(convertToFileSystemChar("Test? Ja, die ist ein Test!"));
... bringt ...
"Test? Ja, die ist ein Test!"

Irgendwie ist mir die Methode replaceAll() scheinbar nicht ganz klar. Hat jemand eine Erklärung?

Edit:
Sollte öfters mal in "Java is och ne Insel" reinguggn. Die Version funktioniert jetzt aber wirklich:


```
private String convertToFileSystemChar(String name) {
    String erg = "";
    Matcher m = Pattern.compile("[a-zA-Z0-9 ]").matcher(name);
    while (m.find()) {
        erg += name.substring(m.start(), m.end());
    }
    return erg;
}
```

Der Vollständigkeit würde ich mich trotzdem über eine funktionierende replaceAll() - Methode freuen 

Edit2:
Ach man, ihr schlaft ja noch alle! replaceAll() gibt nen String zurück und wertet ihn nicht auf die angegebene Instanz aus. Manchmal sieht man den Wald vor lauter Bäumen nicht :autsch:

Nun aber:

```
private String convertToFileSystemChar(String name) {
    return name.replaceAll("[^a-zA-Z0-9 ]", "");
}
```

Hätte ich auch schon an dayaftereh's Beitrag sehen müssen  :cry:


----------



## musiKk (16. Aug 2008)

Keine Funktion bearbeitet Strings direkt, da diese immutable sind.


----------



## TypusMensch (16. Aug 2008)

Ok, vielen Dank. Jetzt will das Ganze soweit erweitern, dass Leerzeichen vorne und hinten abgeschnitten werden. Vorne funktioniert das wunderbar, hinten aber nicht. 

Javadoc sagt:
^ = The beginning of a line
$ = The end of a line

Die beiden Zeilen unterscheiden sich auch dadurch nicht wirklich viel voneinander. Dennoch klappt nur eine von beiden.


```
private String convertToFileSystemChar(String name) {
    name = name.replaceAll("[^a-zA-Z0-9 ]", ""); 
    name = name.replaceAll("^ *", "");
    name = name.replaceAll("$ *", "");
    return name;
}
```


----------



## musiKk (16. Aug 2008)

$ muss an den Schluss, sonst bringts nicht die gewuenschte Wirkung. Also praktisch

```
replaceAll(" *$", "");
```
Deine gewuenschte Funktion liefert aber auch String.trim().


----------

