Как пропустить недопустимые символы в потоке в 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)
мне все равно, если некоторые строки не были прочитаны, но как пропустить недопустимые символы и продолжить чтение строк?
4 ответов
вы можете повлиять на то, как кодировка кодировки обрабатывает недопустимый ввод, вызвав 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")
(или использовать the Charsets
класс С гуавы).
Ну, если это не UTF-8, это что-то другое. Трюк заключается в том, чтобы выяснить, что это что-то еще, но если все, что вы хотите, это избежать ошибок, вы можете использовать кодировку, которая не имеет недопустимых кодов, таких как latin1
:
Source.fromFile(new File( path), "latin1").getLines()
У меня была аналогичная проблема, и один из встроенных кодеков Scala сделал трюк для меня:
Source.fromFile(new File(path))(Codec.ISO8859).getLines()
Если вы хотите избежать недопустимых символов с помощью 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)
}
}
}