让我们直接回答我的问题:我有一个套接字,通过这个套接字/流的所有输入都由我的 SAX 解析器解析。现在,对于某个解析事件,我想从我的 SAX 事件处理程序中关闭套接字/流。另外,我想在解析器仍在工作时从外部关闭流。不幸的是,如果没有解析器抛出异常(意外的文档结束......),我无法做一件事或另一件事。好的,我可以捕捉到这个异常,但是您知道如何安全关闭流的解决方案吗?
3 回答
我认为你不能轻易做到这一点。您为 SAX 解析器提供了一个可供读取的资源(流),然后您将其关闭,而 SAX 解析器仍希望从中读取 - 因此它(并非不合理!)抛出“意外的文档结尾”。
如果您想干净地执行此操作,我认为您已实现的 SAX 解析器处理程序应该在您决定忽略更多事件后静默吞下事件。
例如,您的 等的实现startElement()
应该endElement()
在处理之前检查您是否仍然对这些事件感兴趣。
这样,SAX 解析器就可以干净地运行到文档的末尾,而无需您处理任何更多的事件。
或者,为什么不记录您已关闭输入流的事实,然后当您收到“意外的文档结束”事件时,看看它是否确实是预期的。并且仅在确实出乎意料时才记录错误。
如果您控制文档生成端,您可以设置关闭请求消息发送回服务器并结束传入文档。根据您完整系统的详细信息,这要么是一个丑陋的黑客,要么是一个优雅的解决方案...... :)
这可能很明显,但对于这样的用例,Stax 解析器可能更合适。由于应用程序通过迭代控制读取,它可以在任何给定点关闭解析器和底层流。使用 SAX,您将不得不抛出一个异常,这不是特别优雅或高效。另外,您只能在处理程序中执行此操作。
对于加分,StaxMate可以让使用 Stax 更愉快;没有它,Stax 具有与 SAX 相似的低抽象级别。
最后:如果您的问题是由于套接字而导致的阻塞,那么使用传统的基于阻塞 IO 的 xml 解析器可能很难解决。有一个开源的 xml 解析器可以进行非阻塞(异步)解析,但它鲜为人知,所以我将把这个发现留给感兴趣的读者。:-)