Zeichen Codierung Bei Io In Java
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Zeichencodierung bei Ein-Ausgabe-Operationen auf Files in Java | |
Java verwendet intern UTF-16 als Zeichencodierung und ist damit relativ immun gegenüber Zeichencodierungsproblemen. Ein Umlaut ist ein Umlaut. Aber wenn zeichenketten in Dateien geschrieben oder gelesen werden, dann gibt es mehrere Codierungsmöglichkeiten
Wie wird das gehandelt? Ich habe mir bisher wenig Gedanken gemacht und in einer ISO 8859-1-Welt gelebt. Aber UTF-8 greift immer mehr um sich, und Programme sollten selbstverständlich hier nicht falsch reagieren, also von vornherein mit so etwas rechnen, ohne das der Programmierer daran denken muss. In XML ist die Sache in der Kopfzeile geregelt (dort wird die Codierung des textuellen XML-Files angegeben), und Umschreibungen wie ä oder auch & lt; für "<" funktionieren selbstverständlich. Der Parser hat das zu können und kann das auch.
.....
- Das Problem hat nicht so sehr was mit Java zu tun. In Smalltalk ist z. B. UTF-8 gängig, in Ruby sind Strings zunächst so codiert, wie mein Quellcode (das kann ISO 8859-x sein, Unicode oder gar eine altertümliche Codepage). Generell gilt: Wenn ich mit ASCII-Dateien hantiere, muss ich ein Format festlegen oder raten. Gängige Editoren oder auch die Internetbrowser raten den Zeichencode ganz gut. Aber auch die müssen dabei von gewissen Grundannahmen ausgehen, etwa: Wenn ich auf einem deutschen Windows bin, rechne ich mit deutschen Umlauten und nicht mit chinesischen Schriftzeichen.
Mir ging es nicht um eine allgemeine Darstellung, OK, Problem erkannt, sondern um konkrete Erfahrungen wie in Java damit von Anderen umgegangen wird. Meine bisherigen Erkenntnisse sind folgende:
- Java benutzt intern UTF-16, ist also insoweit intern sehr sauber und flexibel.
- Beim Schreiben auf Dateien / Lesen von Dateien wird aber meist eine Byteweise zeichendarstellung benutzt.
- Es gibt die "älteren" (?) Klassen InputStream und OutputStream und deren Ableitungen. Diese sind auf Bytefelder orientiert und schreiben die Bytefelder direkt in die Dateien. Um Strings zu schreiben, rufe man getBytes(). Hier steht in der Orignialdoku von SUN: ", whic uses the platform's default encoding.". Also macht die VM was passend für Windows (ISO 8859-1, weil ich eben mal mitteleuropäisch im Betriebssystem installiert habe) oder je nachdem. ???
- Die "neueren" (seit JDK 1.1) Klassen sind die Reader und Writer und abgeleitete, in manchen Büchern (Java ist auch eine Insel) steht da gleich mal UTF dabei, es gibt einen write(String str), aber der richtet sich auch offensichtlich nach der plattformspezifschen Installation, die die VM berücksichtigt. Irgendwo habe ich gelesen - finde es heute abend nicht mehr - "man könne was einstellen". Es wird zwar allemal was sinnvolles ausgegeben, bei Windows ebeen ISO 8859-1, ...
- Die Frage ist aber: Wie kann ich bewußt steuern, UTF-8 oder einen anderen bestimmten zeichencode auszugeben (... oder einzulesen)? Bei XML-Files kenne ich eine relativ schlüssige Erklärung (in der Kopfzeile ist die codierung angegeben), aber nicht bei Java.
- Wie geht Ihr anderen damit um?
Ich würde mich über eine Antwort freuen.
Mit freundliche Grüßen, HartmutSchorrig.
- Hallo. Mangels Erfahrung kann ich hier zwar leider keine Tipps geben. Aber eine Anmerkung habe ich. Und zwar zu "In XML ist die Sache in der Kopfzeile geregelt (dort wird die Codierung des textuellen XML-Files angegeben)". Es geht euch doch sicherlich auch so, dass man bei dieser Aussage stutzt, oder? Denn da gibt es doch offenbar ein Henne/Ei-Problem. Man muss doch die Codierung bereits kennen, um die Kopfzeile "richtig" lesen zu können, wodurch man dann die Codierung aber erst erhalten würde. Oops. Da werden also die diversen Parser-Implementierungen beim Lesen der _ersten_ Zeile um gehöriges "Ausprobieren" wohl auch nicht herumkommen (bis etwas Plausibles erkannt wird), stelle ich mir vor. -- VolkerGlave
- Ok, hab' grad in Xerxes 'reingeschaut. Ich begreife zwar nicht auf Anhieb ;-) _was_ die da machen, aber z. B. in ... http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java?view=markup ..., im auf den Kommentar "// perform auto-detect of encoding if necessary" folgenden Code wird anscheinend versucht, das Encoding einer vorliegenden Input-Quelle zu detektieren. Sieht nicht gerade trivial aus. -- Gruß, Volker
- Ich denke, bei XML ist es eben KEIN Problem, weil das dort systematisch gelöst ist. Die erste Zeile lautet (beispiel aus einer XML-datei kopiert:
<?xml version="1.0" encoding="ISO-8859-1"?>
- Nebenbei interessant ist es, dass der Parser (bei JDOM getestet) unbedingt dahinter eine Zeilenschaltung sehen will, sonst streikt er, bei allen anderen Zeilen kann man die Zeilenschaltung vor dem Parsen entfernen (beispielsweise durch Leerzeichen ersetzen).
- Warum ist das systematisch: Weil sich diese Informationen im 7-bit-ASCII-zeichensatz schreiben lassen, und dieser ist bei allen Codierungen gleich (Zeichen von 0x20 bis 0x7e). D.h. bei der ersten zeile spielt der Zeichensatz noch keine Rolle. Also ist die henne garantiert vorhanden, um das Ei zu legen.
- Andere Editoren erkennen teilweise den Zeichensatz selbst, aber das ist, wie Du oben angemerkt hast, eher ein Probierproblem. ... Das dazu, Grüße von Hartmut
- Das ist nicht ganz richtig. Auch für das Lesen der ersten Zeile muss man (bevor man das "encoding" überhaupt erreicht hat) beispielsweise bereits ermittelt haben, ob man pro Zeichen etwa ein oder zwei Byte (oder Mischform) zu lesen hat. Das Henne-/Ei-Problem besteht also in irgendeiner Form sehr wohl. Es ist mir unklar, was du daran nicht begreifst. -- Gruß, Volker
- Entschuldigung, Volker, das ich so unbegriffen wirke. Ich habe einfach nicht daran gedacht, dass es auch Codierungen mit 2 Bytes pro Zeichen (UTF-16) in den Dateien gibt. Mir sind solche Darstellungen mal als Idee vor ein paar Jahren entgegengetreten, offensichtlich hat sich dieses Format aber nicht allgemein durchgesetzt, mir ist es nicht mehr begegenet obwohl ich mir gern Dateien in hex anschaue. Meist wird entweder eine der ISO-8859-codierungen verwendet oder UTF8. Wenn man voraussetzt, dass nur diese 1-Byte-pro-Zeichen-codierung verwendet werden, dann stimmt meine Aussage ganz genau. Die Formate sind übrigens sehr gut erläutert in http://www.de.wikipedia.org/wiki/Ascii. Muss man auch 16-bit-Codierungen und anderes in Files lesen und verstehen, dann ist's freilich ein Henne-Ei-Problem. Aber da ein Kopf eine XML-Datei mit der festen Zeichenfolge "<?xml" anfangen soll, sollte dies recht einfach zu entscheiden sein. Ich habe aber noch nicht in den Xerces-parser hineingeschaut, werde das aber tun sobald ich Zeit finde.
Leider ist das eigentliche Problem aber von niemanden beantwortet worden. mfG HartmutSchorrig
Mal zurück zum Thema:
Es gibt in Java die Möglichkeit ein Byte-array unter Angabe des Zeichensatzes in einen String umzuwandeln.
Umgekehrt geht das auch. Wenn man also den Zeichensatz einer Datei kennt (woher auch immer) hat man die volle Kontrolle. Hier mal ein Beispiel:
// Dateien festlegen
File infile = new File("win.txt");
File outfile= new File("utf.txt");
// bytearray auf Dateigröße - für große Dateien sicherlich suboptimal.
byte[] inbyte = new byte[(int)infile.length()];
FileInputStream instream = new FileInputStream(infile);
FileOutputStream outstream = new FileOutputStream(outfile);
// mal sehen, welche Charsets es so gibt...
System.out.println(Charset.availableCharsets().toString().replaceAll(",", "\n"));
// binäres Lesen der Datei in das Bytearray
instream.read(inbyte);
// jetzt das Bytearray mit definiertem Charset in einen (UTF-16) String wandeln.
String content = new String(inbyte, "ISO-8859-1");
System.out.println(content); // Probeausgabe
// und nun den String in einen Bytestrom des gewünschten Charsets wandeln.
byte[] outbyte = content.getBytes("UTF-8");
outstream.write(outbyte);
instream.close();
outstream.close();
mfG EloiMaelzer
KategorieJava
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 9. November 2006 16:07 (diff))