Зачем очищать CharsetDecoder?

Документация для CharsetDecoder говорит

Декодер всегда должен использоваться путем выполнения следующей последовательности вызовов методов, в дальнейшем называемой операцией декодирования:

  1. Сброс декодера с помощью метода сброса, если он не использовался ранее;

  2. Вызывайте метод декодирования ноль или более раз, пока возможны дополнительные входные данные, передавая false для аргумента endOfInput и заполняя входной буфер и сбрасывая выходной буфер между вызовами;

  3. В последний раз вызовите метод декодирования, передав значение true для аргумента endOfInput; а потом

  4. Вызвать метод сброса, чтобы декодер мог сбрасывать любое внутреннее состояние в выходной буфер.

Кажется, что #3 и #4 делают одно и то же: указывают, что больше нет ввода, поэтому декодер может завершить работу.

Если я сделаю оба, я не уверен, как должна выглядеть моя логика обработки ошибок.

В чем разница между этими двумя операциями и почему они необходимы?

2 ответа

В чем разница между этими двумя операциями?

  • #3 завершает декодирование и обрабатывает некорректный ввод и устанавливает внутреннее состояние декодера в "конец".
  • #4 вызывает абстрактный метод implFlush() (поведение по умолчанию ничего не делает) и устанавливает внутреннее состояние декодера как "очищенное", если оно уже было "концом", в противном случае выдает исключение, если оно еще не "очищено".

а зачем оба нужны?

Они оба необходимы для учета всех возможных реализаций CharsetDecoder. В частности, чтобы дать конкретным подклассам четкое разделение между декодированием, обработкой искаженного ввода и очисткой буферизованных ресурсов.

Если я сделаю оба, я не уверен, как должна выглядеть моя логика обработки ошибок.

API предназначен для сбоя на #4 в любом случае, когда #3 не был вызван успешно. И вообще нет никакого смысла вызывать #3 после предыдущего сбоя #2. Поэтому вам не нужно иметь никакой локальной логики обработки ошибок (блоки try..finally) для вашего CharsetDecoder; просто вызывайте методы один за другим в рекомендованной последовательности.

Поскольку CharsetDecoder является абстрактным классом, никто не догадывается, как появился этот выбор дизайна. Возможно, это могло быть разработано с #3, также обрабатывающим промывку (делегируя implFlush()), вместо того, чтобы полагаться на звонящего, чтобы сделать это.

Также обратите внимание, что #4 является NOOP, если декодер не поддерживает внутреннее состояние.

Другие вопросы по тегам