Mit Bezug auf den folgenden Thread: Java-App: ISO-8859-1-codierte Datei kann nicht korrekt gelesen werden
Wie kann die korrekte Zeichensatzcodierung eines Eingabestreams / einer Eingabedatei am besten programmgesteuert ermittelt werden?
Ich habe versucht, Folgendes zu verwenden:
File in = new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());
Bei einer Datei, von der ich weiß, dass sie mit ISO8859_1 codiert ist, liefert der obige Code ASCII, was nicht korrekt ist und es mir nicht ermöglicht, den Inhalt der Datei korrekt auf der Konsole wiederzugeben.
Reader.getEncoding
Gibt die Codierung zurück, für die der Reader eingerichtet wurde. In Ihrem Fall ist dies die Standardcodierung.Antworten:
Ich habe diese Bibliothek ähnlich wie jchardet zum Erkennen der Codierung in Java verwendet: http://code.google.com/p/juniversalchardet/
quelle
Sie können die Codierung eines beliebigen Bytestreams nicht bestimmen. Dies ist die Natur der Kodierungen. Eine Codierung bedeutet eine Zuordnung zwischen einem Bytewert und seiner Darstellung. Jede Kodierung "könnte" also die richtige sein.
Die Methode getEncoding () gibt die Codierung zurück, die für den Stream eingerichtet wurde (lesen Sie JavaDoc ). Die Kodierung wird für Sie nicht erraten.
Einige Streams geben an, mit welcher Codierung sie erstellt wurden: XML, HTML. Aber kein beliebiger Bytestrom.
Auf jeden Fall könnten Sie versuchen, eine Kodierung selbst zu erraten, wenn Sie müssen. Jede Sprache hat eine gemeinsame Frequenz für jedes Zeichen. Im Englischen erscheint das Zeichen sehr oft, aber ê wird sehr, sehr selten erscheinen. In einem ISO-8859-1-Stream gibt es normalerweise keine 0x00-Zeichen. Aber ein UTF-16-Stream hat viele davon.
Oder: Sie könnten den Benutzer fragen. Ich habe bereits Anwendungen gesehen, die Ihnen einen Ausschnitt der Datei in verschiedenen Codierungen präsentieren und Sie bitten, die "richtige" auszuwählen.
quelle
Überprüfen Sie dies: http://site.icu-project.org/ (icu4j) Sie haben Bibliotheken zum Erkennen von Zeichensätzen von IOStream könnte so einfach sein:
quelle
Hier sind meine Favoriten:
TikaEncodingDetector
Abhängigkeit:
Stichprobe:
GuessEncoding
Abhängigkeit:
Stichprobe:
quelle
CharsetDectector
Klasse.Sie können die Datei auf jeden Fall für einen bestimmten Zeichensatz validieren, indem Sie sie mit a dekodieren
CharsetDecoder
und auf Fehler bei "fehlerhafter Eingabe" oder "nicht zuordnbaren Zeichen" achten. Dies sagt Ihnen natürlich nur, wenn ein Zeichensatz falsch ist. es sagt dir nicht, ob es richtig ist. Dazu benötigen Sie eine Vergleichsbasis, um die dekodierten Ergebnisse auszuwerten. Wissen Sie beispielsweise im Voraus, ob die Zeichen auf eine Teilmenge beschränkt sind oder ob der Text einem strengen Format entspricht? Das Fazit ist, dass die Zeichensatzerkennung ohne Garantie ein Rätselraten ist.quelle
Welche Bibliothek soll ich benutzen?
Zum jetzigen Zeitpunkt entstehen drei Bibliotheken:
Ich schließe Apache Any23 nicht ein da es ICU4j 3.4 unter der Haube verwendet.
Wie man erkennt, wer das Recht erkannt hat Zeichensatz (oder so nah wie möglich)?
Es ist unmöglich, den von den oben genannten Bibliotheken erkannten Zeichensatz zu zertifizieren. Es ist jedoch möglich, sie nacheinander zu fragen und die zurückgegebene Antwort zu bewerten.
Wie kann ich die zurückgegebene Antwort bewerten?
Jeder Antwort kann ein Punkt zugewiesen werden. Je mehr Punkte eine Antwort hat, desto mehr Vertrauen hat der erkannte Zeichensatz. Dies ist eine einfache Bewertungsmethode. Sie können andere ausarbeiten.
Gibt es einen Beispielcode?
Hier ist ein vollständiger Ausschnitt, der die in den vorherigen Zeilen beschriebene Strategie implementiert.
Verbesserungen: Die
guessEncoding
Methode liest den Eingabestream vollständig. Bei großen Eingangsströmen kann dies ein Problem sein. Alle diese Bibliotheken würden den gesamten Eingabestream lesen. Dies würde einen großen Zeitaufwand für die Erkennung des Zeichensatzes bedeuten.Es ist möglich, das anfängliche Laden von Daten auf einige Bytes zu beschränken und die Zeichensatzerkennung nur für diese wenigen Bytes durchzuführen.
quelle
Die obigen Bibliotheken sind einfache Stücklistendetektoren, die natürlich nur funktionieren, wenn sich am Anfang der Datei eine Stückliste befindet. Schauen Sie sich http://jchardet.sourceforge.net/ an, das den Text scannt
quelle
Soweit ich weiß, gibt es in diesem Zusammenhang keine allgemeine Bibliothek, die für alle Arten von Problemen geeignet wäre. Daher sollten Sie für jedes Problem die vorhandenen Bibliotheken testen und die beste auswählen, die den Einschränkungen Ihres Problems entspricht. Oft ist jedoch keine davon geeignet. In diesen Fällen können Sie Ihren eigenen Codierungsdetektor schreiben! Wie ich geschrieben habe ...
Ich habe ein Meta-Java-Tool zum Erkennen der Zeichensatzcodierung von HTML-Webseiten mit IBM ICU4j und Mozilla JCharDet als integrierten Komponenten geschrieben. Hier finden Sie mein Tool. Bitte lesen Sie vor allem den Abschnitt README. In meinem Artikel finden Sie auch einige grundlegende Konzepte für dieses Problem und in seinen Referenzen.
Unten habe ich einige hilfreiche Kommentare abgegeben, die ich in meiner Arbeit erlebt habe:
quelle
Ich habe eine nette Bibliothek von Drittanbietern gefunden, die die tatsächliche Codierung erkennen kann: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding
Ich habe es nicht ausgiebig getestet, aber es scheint zu funktionieren.
quelle
Wenn Sie ICU4J verwenden ( http://icu-project.org/apiref/icu4j/ )
Hier ist mein Code:
Denken Sie daran, alles zu versuchen, was Sie brauchen.
Ich hoffe das funktioniert bei dir.
quelle
Wenn Sie die Kodierung Ihrer Daten nicht kennen, ist es nicht so einfach zu bestimmen, aber Sie könnten versuchen, eine Bibliothek zu verwenden, um sie zu erraten . Auch gibt es eine ähnliche Frage .
quelle
Für ISO8859_1-Dateien gibt es keine einfache Möglichkeit, sie von ASCII zu unterscheiden. Bei Unicode-Dateien kann man dies jedoch im Allgemeinen anhand der ersten paar Bytes der Datei erkennen.
UTF-8- und UTF-16-Dateien enthalten ganz am Anfang der Datei ein Byte Order Mark (BOM). Die Stückliste ist ein nicht unterbrechender Raum mit einer Breite von Null.
Leider erkennt Java dies aus historischen Gründen nicht automatisch. Programme wie Notepad überprüfen die Stückliste und verwenden die entsprechende Codierung. Mit Unix oder Cygwin können Sie die Stückliste mit dem Befehl file überprüfen. Beispielsweise:
Für Java empfehle ich Ihnen, diesen Code zu überprüfen, der die gängigen Dateiformate erkennt und die richtige Codierung auswählt: So lesen Sie eine Datei und geben automatisch die richtige Codierung an
quelle
Eine Alternative zu TikaEncodingDetector ist die Verwendung von Tika AutoDetectReader .
quelle
In einfachem Java:
Bei diesem Ansatz werden die Codierungen einzeln ausprobiert, bis eine funktioniert oder wir keine mehr haben. (Übrigens enthält meine Codierungsliste nur diese Elemente, da es sich um die auf jeder Java-Plattform erforderlichen Zeichensatzimplementierungen handelt: https://docs.oracle.com/javase/9/docs/api/java/nio/charset/Charset.html )
quelle
Können Sie den entsprechenden Zeichensatz im Konstruktor auswählen :
quelle