2010-02-10 6 views
6

Verwendung von Java 6 8-Bit-Zeichen aus einem String zu erhalten:String.getBytes ("ISO-8859-1") gibt mir 16-Bit-Zeichen auf O X

System.out.println(Arrays.toString("öä".getBytes("ISO-8859-1"))); 

gibt mir, auf Linux: [-10, 28] aber OS XI erhalten: [63, 63, 63, -89]

Ich scheine das gleiche Ergebnis zu erhalten, wenn ich die fantastische neue nio CharSetEncoder-Klasse verwende. Was mache ich falsch? Oder ist es Apples Schuld? :)

Antwort

4

konnte ich durch das Speichern der Quelldatei als UTF-8, dieses Problem reproduzieren, dann der Compiler es wirklich MacRoman war zu sagen:

javac -encoding MacRoman Test.java

I javac auf UTF-8 würde die Standard hätte gedacht, auf OSX, aber vielleicht nicht. Oder vielleicht verwenden Sie eine IDE und ist es defragmentieren zu MacRoman. Wie auch immer, Sie müssen stattdessen UTF-8 verwenden.

+0

Es scheint MacRoman ist die Standard-Codierung auf meinem OSX-System. Die Quelldatei mit diesem Literal ist in UTF-8 codiert und analysiert sie fälschlicherweise als MacRoman. Also, wie das zu beheben? Die Angabe von -coding UTF-8 scheint keine gute Option zu sein. Was, wenn ich ein paar gute alte ISO-8859-1-Dateien habe? – lennartcl

+0

Wenn einige Ihrer Dateien ISO-8859-1 sind, müssen Sie sie trotzdem separat kompilieren und * diese * Kodierung angeben. Ich schlage vor, dass Sie immer UTF-8 angeben, sowohl zum Speichern als auch zum Kompilieren. Wenn sich eine MacRoman- oder ISO-8859-1-Datei einschleicht, wissen Sie darüber Bescheid, wenn die Kompilierung fehlschlägt. Es ist viel schwieriger, UTF-8 so zu manipulieren, dass gefälschte Daten akzeptiert werden als bei den meisten anderen Kodierungen. –

+0

Ich dachte, es würde zu ISO-8859-1 wechseln, wenn es eine Datei nicht als UTF-8 lesen könnte. Aber das scheint auf meiner Linux-Box nicht der Fall zu sein. Also '-encoding utf-8' gibt das gleiche Verhalten. Ich fühle mich immer noch nicht ganz wohl bei der Verwendung dieses Schalters, aber mir ist klar, dass ich es auf meiner OSX-Box und ähnlichen Systemen reparieren muss. Ich kann nicht helfen, aber wundere mich, wenn es keine globale "Lösung" gibt, so wird mein System nicht das nächste Mal explodieren, wenn ich auf ein Projekt, das UTF-8 String-Literale verwendet, und ich habe keinen Komponententest um das Problem zu bekommen? – lennartcl

1

Vielleicht ist der Zeichensatz für die Quelle nicht festgelegt (und somit je nach Systemgebietsschema unterschiedlich)?

Können Sie die gleiche kompilierte Klasse auf beiden Systemen ausführen (nicht neu kompilieren)?

+0

Das ist auf jeden Fall der Fall. Dieser korrekt kompilierte Code erzeugt auf allen unterstützten Plattformen die gleiche Ausgabe. –

2

Wie lautet die Codierung der Quelldatei? 63 ist der Code für ?, was bedeutet, "Zeichen kann nicht in die angegebene Codierung konvertiert werden".

Also meine Vermutung ist, dass Sie die Quelldatei auf den Mac kopiert haben und dass die Quelldatei eine Codierung verwendet, die der Mac-Java-Compiler nicht erwartet. IIRC, OS X erwartet, dass die Datei UTF-8 ist.

0

Denken Sie daran, dass es mehr als eine Möglichkeit gibt, Zeichen darzustellen. Mac OS X verwendet standardmäßig Unicode, sodass Ihr String-Literal möglicherweise nicht durch zwei Bytes dargestellt wird. Sie müssen sicherstellen, dass Sie die Zeichenfolge aus dem entsprechenden eingehenden Zeichensatz laden. B. indem Sie in der Quelle ein Escape-Zeichen angeben.

+0

Für was es wert ist, kann ein Akzentzeichen auf zwei Arten dargestellt werden; als einzelne Glyphe (ö) oder als kombinierendes Zeichen (\ u0308 o). – AlBlue

+0

Nun, in diesem Fall ist die Java-Datei Code generiert. Es ist nicht möglich, die Art zu ändern, in der diese Zeichen im Literal codiert werden. – lennartcl

2

Ihre Quelldatei erzeugt "öä" durch die Kombination von Zeichen.

Blick auf diese:

System.out.println(Arrays.toString("\u00F6\u00E4".getBytes("ISO-8859-1"))) 

Dies gilt drucken [-10, -28] wie Sie erwarten (Ich mag es nicht auf diese Weise drucken, aber ich weiß, es ist nicht der Punkt Ihrer Frage) , weil dort die Unicode-Codepunkte angegeben sind, die in Stein gemeißelt sind, und Ihr Texteditor darf nicht "schlau spielen", indem er "o" und "a" mit diakritischen Zeichen kombiniert.

In der Regel, wenn Sie solche Probleme auftreten, möchten Sie wahrscheinlich zwei OS X Un * x Commands verwenden, um herauszufinden, was unter der Haube passiert: file und hexdump sind in solchen Fällen sehr bequem.

Sie möchten sie in Ihrer Quelldatei ausführen und sie in Ihrer Klassendatei ausführen.

+0

Nützliche kleine Werkzeuge. Wie kommt es, dass javac nicht weiß, dass es sich um eine UTF-8-Datei handelt? – lennartcl