Jak odczytać plik tekstowy z mieszanymi kodowaniami w Scali lub Java?

Próbuję przeanalizować plik CSV, najlepiej używając weka.core.converters.CSVLoader. Jednak plik, który posiadam, nie jest prawidłowym plikiem UTF-8. Jest to głównie plik UTF-8, ale niektóre wartości pól są w różnych kodowaniach, więc nie ma kodowania, w którym cały plik jest prawidłowy, ale i tak muszę go przeanalizować. Oprócz korzystania z bibliotek Java, takich jak Weka, pracuję głównie w Scali. Nie jestem nawet w stanie odczytać pliku w scala.io.Source: Na przykład

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

rzuca:

    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$iterrzuca:$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)

Cieszę się, że mogę wyrzucić wszystkie nieprawidłowe postacie lub zastąpić je jakimś manekinem. Będę miał wiele takich tekstów do przetwarzania na różne sposoby i może być konieczne przekazanie danych do różnych bibliotek stron trzecich. Idealnym rozwiązaniem byłoby ustawienie globalne, które spowodowałoby, że wszystkie niskopoziomowe biblioteki Java zignorują niepoprawne bajty w tekście, dzięki czemu będę mógł wywoływać biblioteki stron trzecich na tych danych bez modyfikacji.

ROZWIĄZANIE:

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)

Dzięki + Esailija za wskazanie mi właściwego kierunku. To doprowadziło mnie doJak wykryć nielegalne sekwencje bajtów UTF-8, aby zastąpić je w strumieniu wejściowym Java? który zapewnia podstawowe rozwiązanie Java. W Scali mogę uczynić to domyślnym zachowaniem, czyniąc kodek niejawnym. Myślę, że mogę uczynić go domyślnym zachowaniem dla całego pakietu, umieszczając go w domyślnej definicji kodeka w obiekcie pakietu.

questionAnswers(7)

yourAnswerToTheQuestion