replace und die Umlaute

kodela

Bekanntes Mitglied
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.

Java:
      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
 
Zuletzt bearbeitet:
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
 
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
 
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
 
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
 
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.
 
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:

Java:
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
Java:
String[] lines = str.split("\n");
 
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
 
Zuletzt bearbeitet:
Java ist halt nicht deutschsprachig 😱 Und ein Blick über den Tellerrand mittels Suchmaschine deiner Wahl schadet nie 🙂
 
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
 

Zurück
Oben