【发布时间】:2012-01-24 23:06:56
【问题描述】:
我有一个简单的基于 attoparsec 的pdf parser。在与 iteratee 一起使用之前,它工作正常。 当输入的大小超过缓冲区大小时。
import qualified Data.ByteString as BS
import qualified Data.Iteratee as I
import qualified Data.Attoparsec as P
import qualified Data.Attoparsec.Iteratee as P
import System.Environment (getArgs)
import Control.Monad
import Pdf.Parser.Value
main :: IO ()
main = do
[i] <- getArgs
liftM (P.parseOnly parseValue) (BS.readFile i) >>= print -- works
I.fileDriverRandomVBuf 2048 (P.parserToIteratee parseValue) i >>= print -- works
I.fileDriverRandomVBuf 1024 (P.parserToIteratee parseValue) i >>= print -- DOES NOT works!!!
输入:
<< /Annots [ 404 0 R 547 0 R ] /ArtBox [ 0.000000 0.000000 612.000000 792.000000 ] /BleedBox [ 0.000000 0.000000 612.000000 792.000000 ] /Contents [ 435 0 R 436 0 R 437 0 R 444 0 R 448 0 R 449 0 R 450 0 R 453 0 R ] /CropBox [ 0.000000 0.000000 612.000000 792.000000 ] /Group 544 0 R /MediaBox [ 0.000000 0.000000 612.000000 792.000000 ] /Parent 239 0 R /Resources << /ColorSpace << /CS0 427 0 R /CS1 427 0 R /CS2 428 0 R >> /ExtGState << /GS0 430 0 R /GS1 431 0 R /GS2 469 0 R /GS3 475 0 R /GS4 439 0 R /GS5 480 0 R /GS6 485 0 R /GS7 491 0 R /GS8 497 0 R >> /Font << /C2_0 447 0 R /T1_0 421 0 R /T1_1 422 0 R /T1_2 423 0 R /T1_3 424 0 R /T1_4 425 0 R /T1_5 426 0 R /T1_6 438 0 R >> /ProcSet [ /PDF /Text /ImageC /ImageI ] /Properties << /MC0 << /Metadata 502 0 R >> >> /XObject << /Fm0 451 0 R /Fm1 504 0 R /Fm2 513 0 R /Fm3 515 0 R /Fm4 517 0 R /Fm5 526 0 R /Fm6 528 0 R /Fm7 537 0 R /Fm8 539 0 R /Im0 540 0 R /Im1 541 0 R /Im2 452 0 R /Im3 542 0 R /Im4 543 0 R >> >> /Rotate 0 /StructParents 1 /TrimBox [ 0.000000 0.000000 612.000000 792.000000 ] /Type /Page >>
因此,解析器在没有迭代器的情况下工作,可以处理足够大的块,但不能处理较小的块。迭代中的错误?在 attoparsec-iteratee 中?在我的代码中?有什么解决方法吗?这对我来说是一个非常紧迫的问题。
谢谢。
【问题讨论】:
-
不知道错误在哪里,但是否可以只使用足够大的块大小?或者使用
ByteStrings 代替Iteratees? -
pdf 值可以是任意长的,所以没有足够大的块大小。 Re ByteString:你的意思是惰性IO? Pdf 需要随机访问,参考表通常位于文件末尾。在这种特殊情况下,懒惰的 IO ~= "strict" 会低效地使用内存。
-
Iteratees 是否允许随机访问?我没听说过(没有任何意义,我不是用户)。如果您需要随机访问,可以一次读取整个文件,或者使用一些脚手架来查找和读取文件的某些部分。如果可能,第一个选项要简单得多。 -
@DanielFischer:iteratee 包确实允许随机访问(
zoom-cache在此基础上构建了一个相当复杂的系统)。 -
是的,iteratee 支持
seek。与枚举器相比,这是我最重要的功能。读取整个文件效率低下——仅仅为了获取文档作者就需要数兆字节的内存。而且我懒得手动查找/读取算法:) 有问题的问题是唯一不起作用的。
标签: haskell iterate attoparsec