Por exemplo, eu tenho o seguinte código
Source.fromFile(new File( path), "UTF-8").getLines()
e lança exceção
Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1 at java.nio.charset.CoderResult.throwException(CoderResult.java:260) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:319)
Eu não me importo se algumas linhas não foram lidas, mas como pular caracteres inválidos e continuar lendo linhas?
Você pode influenciar a maneira como a decodificação do conjunto de caracteres manipula inputs inválidas chamando CharsetDecoder.onMalformedInput
.
Normalmente você nunca verá um object CharsetDecoder
diretamente, porque ele será criado nos bastidores para você. Portanto, se você precisar de access, precisará usar a API que permite especificar o CharsetDecoder
diretamente (em vez de apenas o nome da codificação ou o Charset
).
O exemplo mais básico dessa API é o InputStreamReader
:
InputStream in = ...; CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); decoder.onMalformedInput(CodingErrorAction.IGNORE); Reader reader = new InputStreamReader(in, decoder);
Observe que esse código usa os StandardCharsets
class Java 7, para versões anteriores você pode simplesmente substituí-lo por Charset.forName("UTF-8")
(ou usar a class Charsets
de Guava ).
Bem, se não é UTF-8, é outra coisa. O truque é descobrir o que essa outra coisa é, mas se tudo que você quer é evitar os erros, você pode usar uma codificação que não tenha códigos inválidos, como latin1
:
Source.fromFile(new File( path), "latin1").getLines()
Eu tive um problema semelhante, e um dos codecs internos do Scala fez o truque para mim:
Source.fromFile(new File(path))(Codec.ISO8859).getLines()
Se você quiser evitar caracteres inválidos usando o Scala, descobri que isso funcionou para mim.
import java.nio.charset.CodingErrorAction import scala.io._ object HelloWorld { def main(args: Array[String]) = { implicit val codec = Codec("UTF-8") codec.onMalformedInput(CodingErrorAction.REPLACE) codec.onUnmappableCharacter(CodingErrorAction.REPLACE) val dataSource = Source.fromURL("https://www.foo.com") for (line <- dataSource.getLines) { println(line) } } }