Зачем очищать CharsetDecoder?
Документация для CharsetDecoder
говорит
Декодер всегда должен использоваться путем выполнения следующей последовательности вызовов методов, в дальнейшем называемой операцией декодирования:
Сброс декодера с помощью метода сброса, если он не использовался ранее;
Вызывайте метод декодирования ноль или более раз, пока возможны дополнительные входные данные, передавая false для аргумента endOfInput и заполняя входной буфер и сбрасывая выходной буфер между вызовами;
В последний раз вызовите метод декодирования, передав значение true для аргумента endOfInput; а потом
Вызвать метод сброса, чтобы декодер мог сбрасывать любое внутреннее состояние в выходной буфер.
Кажется, что #3 и #4 делают одно и то же: указывают, что больше нет ввода, поэтому декодер может завершить работу.
Если я сделаю оба, я не уверен, как должна выглядеть моя логика обработки ошибок.
В чем разница между этими двумя операциями и почему они необходимы?
2 ответа
В чем разница между этими двумя операциями?
- #3 завершает декодирование и обрабатывает некорректный ввод и устанавливает внутреннее состояние декодера в "конец".
- #4 вызывает абстрактный метод
implFlush()
(поведение по умолчанию ничего не делает) и устанавливает внутреннее состояние декодера как "очищенное", если оно уже было "концом", в противном случае выдает исключение, если оно еще не "очищено".
а зачем оба нужны?
Они оба необходимы для учета всех возможных реализаций CharsetDecoder. В частности, чтобы дать конкретным подклассам четкое разделение между декодированием, обработкой искаженного ввода и очисткой буферизованных ресурсов.
Если я сделаю оба, я не уверен, как должна выглядеть моя логика обработки ошибок.
API предназначен для сбоя на #4 в любом случае, когда #3 не был вызван успешно. И вообще нет никакого смысла вызывать #3 после предыдущего сбоя #2. Поэтому вам не нужно иметь никакой локальной логики обработки ошибок (блоки try..finally) для вашего CharsetDecoder; просто вызывайте методы один за другим в рекомендованной последовательности.
Поскольку CharsetDecoder
является абстрактным классом, никто не догадывается, как появился этот выбор дизайна. Возможно, это могло быть разработано с #3, также обрабатывающим промывку (делегируя implFlush()
), вместо того, чтобы полагаться на звонящего, чтобы сделать это.
Также обратите внимание, что #4 является NOOP, если декодер не поддерживает внутреннее состояние.