2012-03-19 14 views
3

大きな(300-1000mb)xmlファイルを処理できるhaskellライブラリを検索したところ、hexpatが見つかりました。私は/dev/nullに出力をリダイレクトし、それを300メガバイトのファイルを投げてきたテストのためにxmlドキュメントをhexpatで処理する方法を教えてください。

-- Process document before handling error, so we get lazy processing. 

に主張はHaskellウィキにan exampleがあります。メモリ消費量は、プロセスを終了するまで増加し続けました。機能は現在、一定のメモリを使用してその結果

process :: String -> IO() 
process filename = do 
    inputText <- L.readFile filename 
    let (xml, mErr) = parse defaultParseOptions inputText :: (UNode String,  Maybe XMLParseError) 

    hFile <- openFile "/dev/null" WriteMode 
    L.hPutStr hFile $ format xml 
    hClose hFile 

    return() 

は、今私がprocess関数からエラー処理を削除しました。エラー処理の結果、大量のメモリが消費されるのはなぜですか?

xmlmErrは、parseの呼び出し後、2つの別々の評価されていないサンクです。 format xmlxmlを評価し、 'mErr'の評価ツリーを構築しますか?はいの場合は、一定のメモリを使用している間にエラーを処理する方法はありますか?

http://www.haskell.org/haskellwiki/Hexpat/

+0

十分な評判を持つ人がこの質問に 'hexpat'タグを追加してもらえますか? – fho

+0

完了 - 1年以上経過しています。 –

答えて

1

私はhexpatに権威をもって話すことはできませんが、一般的に、エラー処理は、ファイル全体をメモリに読み込むためにあなたを強制します。入力のどこにでもエラーがない場合にのみ結果を出力する場合は、出力を生成する前に入力全体を読み取る必要があります。私が言ったように

が、私は本当にhexpatを知りませんが、XML-導管と、あなたが何かを行うことができます:

try $ runResourceT $ parseFile def inputFile $$ renderBytes def =$ sinkFile outputFile 

それは一定のメモリを使用しますが、処理中にエラーがある場合、例外をスローします(tryがキャッチします)。欠点は、出力ファイルが破損している可能性があることです。私の推測では、あなたの最善の策は、一時ファイルに出力することであり、プロセス全体が完了したら、一時ファイルを出力ファイルに移動してください。例外的に、一時ファイルを削除するだけです。

+0

hmm ...私は実際には、haskellのすべてのXMLライブラリに混乱しています。 * HXT *は「最も良い」(すなわち、最も表現力豊かで完全な)APIであるようです。しかし、私は大きなファイルを処理するのに成功していませんでした。 * Hexpat *は実際には*エラー値に触れない限り正常に動作します。 – fho

関連する問題