如何使用hextat延迟处理xml文档



在搜索可以处理大型(300-1000mb)xml文件的haskell库时,我遇到了hextat。Haskell Wiki中有一个例子声称

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

出于测试目的,我将输出重定向到/dev/null,并向其抛出一个300mb的文件。内存消耗一直在增加,直到我不得不终止进程。

现在我从process函数中删除了错误处理:

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 ()

因此,该函数现在使用常量内存。为什么错误处理会导致大量内存消耗?

据我所知,xmlmErr是在调用parse之后的两个独立的未赋值的thunk。format xml是否评估xml并构建'mErr'的评估树?如果是,有没有一种方法可以在使用常量内存的同时处理错误?

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

我不能在hexpat上与权威人士交谈,但通常情况下,错误处理会迫使您将整个文件读取到内存中。如果只想在输入中没有任何错误的情况下打印出结果,则需要在生成输出之前读取整个输入。

正如我所说,我真的不知道hextat,但有了xml管道,你可以做一些类似的事情:

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

它将使用恒定内存,如果在处理中出现任何错误,它将抛出一个异常(try将捕获该异常)。缺点是输出文件可能已损坏。我的猜测是,最好的选择是输出到一个临时文件,在整个过程完成后,将临时文件移动到输出文件。在任何异常情况下,只需删除临时文件即可。

最新更新