# replace und die Umlaute



## kodela (8. Feb 2010)

Hallo zusammen,

ich habe mir eine simple Anwendung geschrieben, mit der ich grundsätzlich in beliebigen, speziell jedoch in html-Dateien, welche in einem Ordner einschließlich Unterordner liegen, beliebige Textteile ersetzen kann. Bisher habe ich diese Anwendung vor allem dafür verwendet, Pfadbezeichnungen zu verändern. Jetzt wollte ich sie auch dafür verwenden, nicht konvertierte deutsche Umlaute in das UTF-8 Format umzuwandeln. Für den Test habe ich mir eine kurze HTML-Datei geschrieben, in der alle deutschen Sonderzeichen vertreten sind.

Hier ist dann der Teil, in welchem die Ersetzungen über die replace()-Methode vorgenommen werden soll. Nur zum Verständnis: In liste[] sind alle gefundenen HTML-Dateien, die nach der Ersetzung wieder abgespeichert werden.


```
BufferedReader reader;

      try {
          reader = new BufferedReader(new FileReader(liste[i]));
          ArrayList<String> values = new ArrayList<String>();

          String zeile = reader.readLine();                   // erste Zeile einlesen
          while (zeile != null) {                             // solange erfolgreich
              zeile = zeile.replace(suchText, ersatzText);    // korrigieren
              values.add((zeile + "\n").toString());          // Zeile in Liste
              zeile = reader.readLine();                      // nächste Zeile einlesen
       }
       reader.close();
```

Nun passiert bei mir etwas sehr eigenartiges: In den eingelesenen Zeilen sind die Sonderzeichen als Literale dargestellt und zwar für jedes Sonderzeichen der selbe Code, nämlich '\ufffd'. Dieser entspricht keinem mir bekannten UTF-8 Code und wird von replace() durch das kleine 'ö' ersetzt.

Kann mir jemand erklären, woran das liegt, welchen Fehler ich hier mache.

Im voraus schon einmal einen schönen Dank für jeden Hinweis.

Mit freundlichem Gruß,

Konrad


----------



## tuxedo (8. Feb 2010)

Was hälst du davon die Datei mit einem entsprechenden Charset zu lesen und mit UTF-8 Charset wieder zu schreiben?

Das sollten nicht mehr als 10 Zeilen Code sein und erspart die den Ersetzungsaufwand.

- Alex


----------



## kodela (8. Feb 2010)

Hallo Alex,

ehrlich gesagt, ich beschäftige mich erst seit rund drei Wochen intensiver mit Java und habe mit Charsets bisher noch keinerlei Erfahrung. Nur, es geht in meiner Anwendung grundsätzlich ja nicht um das Ersetzten von Sonderzeichen, sondern mehr um die Ersetzung von Adressen oder ähnlichen Textteilen. Dafür ist wohl Charset nicht so besonders geeignet. Das mit den Sonderzeichen ist eigentlich nur ein Nebeneffekt. Trotzdem Danke für Deinen Hinweis, werde mich also auch mit den Charsets vertraut machen.

Mit freundlichem Gruß,

Konrad


----------



## kodela (9. Feb 2010)

Hallo Forumsfreunde,

mittlerweile steht fest, dass es nicht wie ursprünglich angenommen ein Problem mit replace() ist. Es liegt einwandfrei an readLine(), mit der ich Zeile für Zeile einlese. Der von readLine() übergebene String entspricht nicht der einzulesenden Zeile. Alle Sonderzeichen werden einheitlich durch "\ufffd" ersetzt.

Wer hat eine Ahnung, woran das liegen kann.

Mit freundlichem Gruß,

Konrad


----------



## kodela (9. Feb 2010)

Hallo Forumsfreunde,

mittlerweile steht fest, dass es nicht wie ursprünglich angenommen ein Problem mit replace() ist. Es liegt einwandfrei an readLine(), mit der ich Zeile für Zeile einlese. Der von readLine() übergebene String entspricht nicht der einzulesenden Zeile. Alle Sonderzeichen werden einheitlich durch "\ufffd" ersetzt.

Wer hat eine Ahnung, woran das liegen Kann.

Mit freundlichem Gruß,

Konrad


----------



## tuxedo (10. Feb 2010)

Hab ich eben gefunden:



			
				http://1001javatips.com/FileReaderclass.htm hat gesagt.:
			
		

> You cannot correctly read the contents of non-UTF-16 files with FileReader.  That's because you cannot change Java's Unicode's UTF-16 default character encoding using FileReader's constructors.  These constructors do not have a provision for specifying the CharSet of the input file. To specify another CharSet yourself, so that you can correctly read the characters of a non-UTF-16 file, chain an InputStreamReader which specifies the necessary CharSet to a FileInputStream.    See   InputStreamReader class  for an example.


----------



## Gast2 (10. Feb 2010)

Ich verstehe noch nicht ganz das Problem. Wie sieht jetzt die HTML datei aus?

Steht da jetzt z.B. ö drin oder \u00f6 oder &ouml;?
Ich gehe jetzt mal von "ö" steht im text aus:


```
FileInputStream fis = new FileInputStream("meinfile.txt");
InputStreamReader isr = new InputStreamReader(fis, "ISO-8859-1");
StringBuilder buffer = new StringBuilder();
int c;
while ((c = isr.read()) != -1) {
    buffer.append((char) c);
}
String str = buffer.toString();
str = str.replace("ö", "\u00f6 oder \\u00f6 oder &ouml; oder ...");
```

Wenn du das noch Zeilenweise haben willst könntest du bei \n oder \r\n splitten

```
String[] lines = str.split("\n");
```


----------



## kodela (10. Feb 2010)

Hallo Alex,

herzlichen Dank für den Hinweis. Ich frage mich nur, warum ich in der deutschsprachigen Literatur keinen Hinweis darauf gefunden habe, dass readLine() nur sehr eingeschränkt verwendbar ist.

Mit freundlichem Gruß,

Konrad


----------



## tuxedo (10. Feb 2010)

Java ist halt nicht deutschsprachig  Und ein Blick über den Tellerrand mittels Suchmaschine deiner Wahl schadet nie


----------



## Gast2 (10. Feb 2010)

Ah, jetzt verstehe ich es ... es ging nur um das readLine()


----------



## kodela (10. Feb 2010)

Hallo fassy,

die einzulesende Datei kann von jedem beliebigen Typ sein, sie muss nur auch einen Text enthalten, der mit readLine() gelesen werden soll. Das sind nur bei mir überwiegend HTML-Dateien,  aber bei TXT-Dateien haben wir das selbe Problem. 

Du könntest jetzt natürlich fragen, warum ich die Dateien mit readLine() einlese und nicht, wie Du es vorschlägst, mit read(). Ganz einfach, weil es readLine() gibt und ich die Daten eben zeilenweise behandeln wollte. Dass dies in der Mehrzahl aller Fälle nicht möglich ist, habe ich weder in der offiziellen Java-Dokumentation zu readLine() noch in einer der wichtigsten deutschsprachigen Publikationen entdecken können. 

Ich muss allerdings zugeben, dass in der Dokumentaion zur Klasse *FileReader* darauf hingewiesen wird.

Ich danke Dir jedenfalls für den Vorschlag, wie man das Problem mir dem FileReader umgehen kann.

Mit freundlichem Gruß,

Konrad


----------

