Лучший способ закрыть поток, который синтаксический анализатор SAX читает в процессе синтаксического анализа?

Давайте сразу перейдем к моему вопросу: у меня есть сокет, и все входные данные, поступающие через этот сокет/поток, анализируются моим синтаксическим анализатором SAX. Теперь, после определенного события синтаксического анализа, я хотел бы закрыть сокет/поток из моего обработчика событий SAX. Кроме того, я хочу закрыть поток извне в определенном случае, пока парсер все еще работает. К сожалению, я не могу сделать ни то, ни другое без исключения, выброшенного синтаксическим анализатором (неожиданное окончание документа...). Хорошо, я мог бы поймать это исключение, но знаете ли вы решение, как безопасно закрыть поток?


person balu    schedule 12.04.2009    source источник


Ответы (3)


Я не думаю, что вы можете легко сделать это. Вы предоставляете синтаксическому анализатору SAX ресурс (поток) для чтения, а затем вы его закрываете, а синтаксический анализатор SAX все еще ожидает чтения из него - следовательно, он (небезосновательно!) выдает «неожиданное окончание документа».

Если вы хотите сделать это чисто, я думаю, что ваш парсер SAX , который вы реализовали, должен автоматически проглатывать события, как только вы решили игнорировать дальнейшие события.

например ваши реализации startElement(), endElement() и т. д. должны выполнять проверку, чтобы убедиться, что вы все еще заинтересованы в этих событиях перед обработкой.

Таким образом, синтаксический анализатор SAX может работать без ошибок до конца документа без обработки каких-либо событий.

В качестве альтернативы, почему бы не записать тот факт, что вы закрыли входной поток, а затем, когда вы получите событие «неожиданное завершение документа», посмотрите, действительно ли оно было ожидаемым. И регистрируйте ошибку только в том случае, если она действительно была неожиданной.

person Brian Agnew    schedule 12.04.2009
comment
Мне это нравится, если предположить, что документ когда-либо имеет конец, поскольку это просто данные, поступающие через сокет. В противном случае просто поймайте исключение. - person Jonathan Adelson; 12.04.2009

Если вы контролируете завершение создания документа, вы можете настроить сообщение запроса на закрытие для отправки обратно на сервер и завершения входящего документа. В зависимости от деталей вашей полной системы, это либо уродливый хак, либо элегантное решение... :)

person Jonathan Adelson    schedule 12.04.2009

Это может быть очевидным, но для подобных случаев лучше подойдет анализатор Stax. Поскольку приложение контролирует чтение посредством итерации, оно может закрыть синтаксический анализатор и базовый поток в любой момент. С SAX вам придется генерировать исключение, что не особенно элегантно или эффективно. Кроме того, вы можете сделать это только из обработчика.

За дополнительные баллы StaxMate можно сделать использование Stax более приятным; без него Stax имеет такой же низкий уровень абстракции, как и SAX.

Наконец: если ваша проблема связана с блокировкой из-за сокетов, ее может быть трудно решить с помощью традиционных синтаксических анализаторов xml на основе блокирующего ввода-вывода. Существует один синтаксический анализатор xml с открытым исходным кодом, который может выполнять неблокирующий (асинхронный) анализ, но он довольно малоизвестен, поэтому я оставлю это открытие заинтересованным читателям. :-)

person StaxMan    schedule 13.04.2009