2010-09-27 1 views
16

Этот файл не под моим контролем. Большинство байтовых последовательностей действительны UTF-8, это не ISO-8859-1 (или другое кодирование). Я хочу сделать все возможное, чтобы извлечь как можно больше информации.Как обнаружить незаконные последовательности байтов UTF-8 для их замены в java inputstream?

Файл содержит несколько нелегальных последовательностей байт, те должны быть заменяют замены символа.

Это не простая задача, это кажется, это требует некоторого знания о государственной машине UTF-8.

Oracle имеет оболочку, которая делает то, что мне нужно:
UTF8ValidationFilter javadoc

Есть ли что-то подобное доступно (коммерчески или как свободное программное обеспечение)?

Благодаря
-stephan

Решение:

final BufferedInputStream in = new BufferedInputStream(istream); 
final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder(); 
charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE); 
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 
final Reader inputReader = new InputStreamReader(in, charsetDecoder); 
+10

Ненавижу это. производители контента должны создавать достоверный контент, а не просить потребителей угадывать и исправлять. Это вызвало столько проблем в нашей отрасли. – irreputable

ответ

12

java.nio.charset.CharsetDecoder делает то, что вам нужно. Этот класс обеспечивает кодирование символов с определяемыми пользователем действиями при различных видах ошибок (см. onMalformedInput() и onUnmappableCharacter()).

CharsetDecoder пишет на OutputStream, который вы можете направить в InputStream с помощью java.io.PipedOutputStream, эффективно создавая отфильтрованного InputStream.

+0

Это было быстро полезно, спасибо. – user85155

+0

@ Хеннинг - что, если я хочу знать, на какой линии там плохие персонажи? – Dejell

+1

@Dejel вы можете разделить вход в строки и попытаться обнаружить ошибку в строке. –

0

Одним из способов было бы прочитать первые несколько байт для проверки Byte Order Mark (если существует). Дополнительная информация о спецификации: http://en.wikipedia.org/wiki/Byte_order_mark В данном URL-адресе вы найдете таблицу байтов спецификации. Однако одна из проблем заключается в том, что UTF-8 не требует использования спецификации в своем «заголовке». Существует еще один способ решения проблемы - распознавание образов (каждый раз считывается несколько байтов-8 бит). Во всяком случае, это сложное решение ..

+0

Проблема не была спецификацией, она уже была удалена. Там ист BOMStripperInputStream плавающие вокруг, что помогает здесь: http://code.google.com/p/train-graph/source/browse/trunk/src/org/paradise/etrc/data/BOMStripperInputStream.java?r=31 – user85155

0

поведение вы хотите, уже по умолчанию для InputStreamReader. Поэтому нет необходимости указывать его самостоятельно. Этого достаточно:

final BufferedInputStream in = new BufferedInputStream(istream); 
final Reader inputReader = new InputStreamReader(in, StandardCharsets.UTF_8); 

 Смежные вопросы

  • Нет связанных вопросов^_^