Wie lese ich eine Textdatei mit gemischten Codierungen in Scala oder Java?

Ich versuche, eine CSV-Datei zu analysieren, idealerweise mit weka.core.converters.CSVLoader. Die Datei, die ich habe, ist jedoch keine gültige UTF-8-Datei. Es handelt sich meistens um eine UTF-8-Datei, aber einige der Feldwerte sind unterschiedlich codiert. Es gibt also keine Codierung, in der die gesamte Datei gültig ist, aber ich muss sie trotzdem analysieren. Neben Java-Bibliotheken wie Weka arbeite ich hauptsächlich in Scala. Ich kann die Datei in scala.io nicht einmal lesen. Quelle: Zum Beispiel

Source.
  fromFile(filename)("UTF-8").
  foreach(print);

wirft:

    java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:337)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:176)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:153)
at java.io.BufferedReader.read(BufferedReader.java:174)
at scala.io.BufferedSource$anonfun$iterwirft:$anonfun$apply$mcI$sp$1.apply$mcI$sp(BufferedSource.scala:38)
at scala.io.Codec.wrap(Codec.scala:64)
at scala.io.BufferedSource$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.io.BufferedSource$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.collection.Iterator$anon$14.next(Iterator.scala:150)
at scala.collection.Iterator$anon$25.hasNext(Iterator.scala:562)
at scala.collection.Iterator$anon$19.hasNext(Iterator.scala:400)
at scala.io.Source.hasNext(Source.scala:238)
at scala.collection.Iterator$class.foreach(Iterator.scala:772)
at scala.io.Source.foreach(Source.scala:181)

Ich bin vollkommen glücklich, alle ungültigen Zeichen wegzuwerfen oder sie durch eine Attrappe zu ersetzen. Ich werde eine Menge solcher Texte haben, um sie auf verschiedene Arten zu verarbeiten, und muss sie möglicherweise an verschiedene Bibliotheken von Drittanbietern weitergeben. Eine ideale Lösung wäre eine Art globale Einstellung, die dazu führen würde, dass alle Java-Bibliotheken auf niedriger Ebene ungültige Bytes im Text ignorieren, sodass ich Bibliotheken von Drittanbietern für diese Daten ohne Änderung aufrufen kann.

LÖSUNG:

import java.nio.charset.CodingErrorAction
import scala.io.Codec

implicit val codec = Codec("UTF-8")
codec.onMalformedInput(CodingErrorAction.REPLACE)
codec.onUnmappableCharacter(CodingErrorAction.REPLACE)

val src = Source.
  fromFile(filename).
  foreach(print)

Vielen Dank an + Esailija für den Hinweis in die richtige Richtung. Das führte mich zuWie erkenne ich ungültige UTF-8-Byte-Sequenzen, um sie im Java-Inputstream zu ersetzen? welches die Kern Java Lösung zur Verfügung stellt. In Scala kann ich dies zum Standardverhalten machen, indem ich den Codec implizite. Ich denke, ich kann es zum Standardverhalten für das gesamte Paket machen, indem ich es in die implizite Codec-Definition des Paketobjekts setze.

Antworten auf die Frage(7)

Ihre Antwort auf die Frage