私は Android で RSS フィード パーサーに取り組んでおり、ほとんどの状況で完全に動作する SAX パーサーを実装しました。
ただし、いくつかのテスト フィードで問題が発生しました。指定された数のフィード アイテムを解析した後、SAXException をスローしてパーサーを停止します。私の知る限り、これが正しい方法です。ほとんどのフィードでは、これにより解析が停止し、私の catch ブロック (以下を参照) が StopParsingException を処理してログに記録します。
ただし、一部のフィードでは、パーサーは解析を停止しますが、例外がスローされてから catch ブロックが実行されるまでの間に長い遅延があり、その間解析は行われませんが、ファイル全体をダウンロードするのに十分な時間が経過します (これは起こっていると思います)。
これが私のセットアップとエラー処理コードです:
public boolean parse(){
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
URL u = new URL(mUrl);
URLConnection UC = u.openConnection();
UC.setConnectTimeout(CONNECT_TIMEOUT);
UC.setReadTimeout(CONNECT_TIMEOUT);
InputStreamReader r = new InputStreamReader(UC.getInputStream());
parser.parse(new InputSource(r), this);
}catch(SAXException sax)
{
Exception ex = sax.getException();
if(ex != null)
{
if(ex instanceof StopParsingException)
{
//Feed was intentionally stopped (i.e. reached episode limit)
DebugLog.w(TAG, "Feed update stopped for: " + mUrl, ex);
return true;
}else
{
//Something went wrong, non-standard error
DebugLog.e(TAG, "Feed update failed for: " + mUrl, ex);
return false;
}
}else{
//Something went wrong, non-standard error
DebugLog.e(TAG, "Feed update failed fatally for: " + mUrl, sax);
return false;
}
}
catch(Exception e){
DebugLog.e(TAG, "Unknown parse error on feed: "+mUrl, e);
return false;
}
DebugLog.i(TAG, "Entire Feed Parsed successfully: "+mUrl);
return true;
}
条件の 1 つが満たされた場合、次のコードを使用します。
throw (new SAXException(new StopParsingException("Max Items reached")));
たとえば、パーサーを停止します。
私の推測では、例外をスローすると、SAXParser は動作を停止しますが、InputSteamReader はサーバーからの rss フィードのダウンロードを続行します。これは、ログが明らかにするタイミングとほぼ同じだからです。
一部のサーバーのみが私と連携しないようにする接続設定に何か問題がありますか?
または、この問題が発生しないように、SAXException をスローする前にその InputStream を安全に直接停止する方法はありますか?