Подтвердить что ты не робот

Как пропускать недопустимые символы в потоке в Java/Scala?

Например, у меня есть следующий код

Source.fromFile(new File( path), "UTF-8").getLines()

и генерирует исключение

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)

Мне все равно, если некоторые строки не были прочитаны, но как пропустить недопустимые символы и продолжить чтение строк?

4b9b3361

Ответ 1

Вы можете влиять на то, что декодер charset обрабатывает недопустимый ввод, вызывая CharsetDecoder.onMalformedInput.

Обычно вы никогда не увидите объект CharsetDecoder напрямую, потому что он будет создан за кулисами для вас. Поэтому, если вам нужен доступ к нему, вам нужно будет использовать API, который позволяет вам напрямую указывать CharsetDecoder (а не только имя кодировки или Charset).

Самый простой пример такого API - InputStreamReader:

InputStream in = ...;
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
decoder.onMalformedInput(CodingErrorAction.IGNORE);
Reader reader = new InputStreamReader(in, decoder);

Обратите внимание, что этот код использует класс Java 7 StandardCharsets, для более ранних версий вы можете просто заменить его Charset.forName("UTF-8") (или используйте класс Charsets из Guava).

Ответ 2

Хорошо, если это не UTF-8, это нечто другое. Трюк заключается в том, чтобы узнать, что это такое, но если вы хотите избежать ошибок, вы можете использовать кодировку, которая не имеет неверных кодов, например latin1:

Source.fromFile(new File( path), "latin1").getLines()

Ответ 3

У меня была аналогичная проблема, и один из Scala встроенных кодеков помогло:

Source.fromFile(new File(path))(Codec.ISO8859).getLines()

Ответ 4

Если вы хотите избежать недопустимых символов с помощью Scala, я обнаружил, что это сработало для меня.

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)
    }
  }
}