Java-compiler-Plattform-file-encoding problem
Kürzlich traf ich eine Datei character encoding Problem, ich kann mich nicht erinnern, jemals konfrontiert. Es ist durchaus üblich, um bewusst sein, der Zeichen-Codierung von text-Dateien und code schreiben, Griffe Codierung korrekt, wenn Sie laufen auf verschiedenen Plattformen. Aber das problem, das ich fand, war, verursacht durch Zusammenstellung auf einer anderen Plattform, von der execution platform. Das war ganz unerwartet, weil in meiner Erfahrung, wenn javac erzeugt eine class-Datei, die wichtige Parameter sind die java-Quell-und Ziel-Parameter, und die version des JDK zu tun kompilieren. Ich meine den Fall, Klassen compiliert mit JDK 1.6.0_22 auf Mac OS X anders Verhalten als Klassen kompiliert mit 1.6.0_23-b05 auf Linux, bei der Ausführung unter Mac OS X. Der angegebenen Quelle und Ziel 1.4.
Einen String kodiert als ISO 8859_1 im Speicher auf den Datenträger geschrieben wurde mit einem PrintStream println-Methode. Je nachdem, auf welcher Plattform der Java-code KOMPILIERT wurde, wird der string war anders geschrieben. Diese führen zu einem Fehler. Der fix für den bug war, geben Sie der Datei die Kodierung explizit beim schreiben und Lesen der Datei.
Was mich überrascht hat war, dass das Verhalten Unterschied sich je nachdem, wo die Klassen kompiliert wurden, nicht auf welcher Plattform der Klasse ausgeführt wurde. Ich bin sehr vertraut mit Java-code verhält sich anders, wenn Sie auf verschiedenen Plattformen. Aber es ist ein bisschen beängstigend, wenn der gleiche code, kompiliert auf verschiedenen Plattformen, läuft anders als auf der gleichen Plattform.
Hat jemand auf dieses spezifische problem? Es scheint schlecht für Sie beliebigen Java-code, der liest und schreibt strings in Datei ohne explizite Angabe der Zeichenkodierung. Und wie oft wird das gemacht?
- war die problematische Datei als utf-8 kodiert? Gab es problematische Zeichen in der Quelle, oder waren die Zeichen nur ungültige nach die Zusammenstellung nur auf einer Maschine?
- War dies für Sie zusammengestellt-Klassen mit static final (Zusammenstellung statische Finale "backt" die strings in der Klasse)? oder wenn Sie sagen, auf die Festplatte geschrieben werden, die Sie serialisieren der Daten? serialisieren einer Klasse-Instanz? Serialisierung-Methode zusammengestellt werden mit der Standardeinstellung(d.h. kompilieren Plattform) Codierung?
- B.: In der Tat, alle string-Literale und andere compile-Zeit-Konstante strings sind "eher gebacken" in der Klasse, nicht nur static final ones.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es keine solche Dinge wie eine ein String, der verschlüsselt wurde, als ISO-8859-1 im Speicher. Java-Strings im Speicher sind immer Unicode-strings. (Codiert in UTF-16, aber Sie nicht wirklich brauchen, um jetzt diese).
Die Codierung kommt nur in spielen, wenn Sie input-oder output-string - dann, da keine explizite Codierung, verwendet das system standardmäßig (was auf einigen Systemen hängt davon ab, Benutzer-Einstellungen).
Wie gesagt von McDowell, die tatsächliche Kodierung der Quelldatei abgestimmt werden sollte, indem die Kodierung der compiler übernimmt über Ihre Quell-Datei, sonst bekommen Sie Probleme, wie Sie beobachtet. Dies erreichen Sie durch verschiedene Mittel:
-encoding
option des Compilers, indem Sie die Kodierung der Quelldatei. (Mit ant, legen Sie dieencoding=
parameter.)recode
) ändern Sie die Codierung der Datei die Standard-compiler.native2ascii
(mit der rechten-encoding
option) zum übersetzen der Quelldatei in ASCII mit\uXXXX
-escapes.In die Letzte Falle, die Sie später erstellen kann diese Datei überall mit jedem Standard-Codierung, so kann dies der Weg zu gehen, wenn man den sourcecode der Verschlüsselung-nicht bewusst Personen zu kompilieren irgendwo.
Wenn Sie ein größeres Projekt, das aus mehr als einer Datei, sollten Sie alle die gleiche Codierung, da der compiler hat nur einen solchen Schalter, nicht mehrere.
In allen Projekten hatte ich in den letzten Jahren habe ich immer encode alle meine Dateien in UTF-8, und in meinem ant-buildfile gesetzt, die
encoding="utf-8"
parameter an den javac-task. (Mein editor ist intelligent genug, um automatisch erkennt die Codierung, aber ich die standardmäßig UTF-8.)Die Codierung Fragen zu anderen source-code-handling-tools wie javadoc. (Dort sollten Sie zusätzlich die
-charset
und-docencoding
Optionen für die Ausgabe - Sie sollten übereinstimmen, sondern können unterschiedlich sein, um die source--encoding
.)Ich würde raten, dass es eine transcoding-Problem während der Kompilierung der Bühne und der compiler fehlt die Richtung, die Codierung der Quell-Datei (z.B. siehe die javac
-encoding
Schalter).Compiler in der Regel verwenden Sie den system-Standard-Codierung, wenn Sie sind nicht spezifisch, die kann dazu führen, string-und char-Literale werden beschädigt (intern, Java-bytecode nutzt eine modifizierte UTF-8-form, so werden die Binärdateien portable). Dies ist der einzige Weg, ich kann mir vorstellen, dass Probleme eingeführt, die bei der Kompilierung.
Ich geschrieben habe, ein wenig über dieses hier.
Immer escape-codes (e.g
\uxxxx
) in den Quelldateien, und dies wird nicht ein problem sein. @Paulo erwähnt, aber ich wollte es nennen ausdrücklich.Ich hatte ähnliche Probleme bei der Verwendung von Variablen-Namen, die nicht-ascii (Σ, σ, Δ, etc), wenn dabei mathematische Formel. Unter linux verwendet UTF-8-Codierung bei der Interpretation. Auf windows beschwerte sich über die ungültigen Namen auf, weil windows mit ISO-LATIN-1. Die Lösung war, die Kodierung angeben, die in der ant-script, das ich verwendet, um kompilieren Sie diese Dateien.
Sigma
(odersum
),sigma
,delta
und so weiter, anstatt mit den richtigen griechischen Buchstaben. Habe ich einmal erstellt eine variable mit dem Namenℕ
. Ich wollte es nennenℕ₀
, aber javac nicht akzeptieren, da₀
ist nicht eine Ziffer für Java.