从文件读取和MongoDB GridFS之间的区别?

时间:2014-12-23 08:43:28

标签: python mongodb pdf gridfs pdfminer

我正在使用Python Flask framework开发一个处理PDF的网站。我将PDF文件存储在MongoDB中,当我需要将它们提供给访问用户时,它可以正常工作。我现在需要做一些文本和图像提取,我使用pdfminer library。当我使用pdf2txt.py并从文件系统提供文件时,此行(context here)几乎立即起作用:

for page in PDFPage.get_pages(file('ticket.pdf', 'rb'), pagenos, maxpages=maxpages, password=password, caching=caching, check_extractable=True): pass

但是当我编辑代码以便从MongoDB提供GridFS对象时,第二行(在完成后退之后)大约需要8秒才能成功(结果与上面的代码相同) :

document = UserDocument.objects.first()
for page in PDFPage.get_pages(document.file_, pagenos, maxpages=maxpages, password=password, caching=caching, check_extractable=True): pass

这让我感到惊讶,因为我假设从我的MongoDB中获取文件或从文件系统中获取文件会返回相同的结果(它在浏览器中渲染相同),但显然它是不一样的。

有没有人知道这两者之间的区别是什么导致这个调用需要这么长时间,更重要的是我如何解决它?欢迎所有提示!

1 个答案:

答案 0 :(得分:0)

回答我自己的问题:事实证明,因为字符串是在Python中实现的,这意味着任何字符串操作都会创建新的字符串,如果您有多兆字节的字符串(即重复复制“余数”),这些字符串可能会失控。处理成新字符串的字符串会表现出减速效果。)

显然,这突出了pdfminer库编写错误的事实。所以我有两个选择:

  1. 编辑pdfminer lib并发送拉取请求。
  2. 将文件写入文件系统或StringIO字符串缓冲区并从中读出。
  3. 虽然选项1是最好的选择,但我不知道这个lib或时间来学习这个。所以我选择了使用字符串缓冲区的选项2:

    document = UserDocument.objects.first()
    fp = StringIO()
    fp.write(document.file_.read())  # Also takes about 0.8 sec, but thats still faster than 8 seconds.
    for page in PDFPage.get_pages(file('ticket.pdf', 'rb'), pagenos, maxpages=maxpages, password=password, caching=caching, check_extractable=True): pass
    

    这现在需要大约1秒,虽然仍然很慢,但现在仍然可行。如果我们进一步处理开发过程,我们将看看是否可以分叉和改进pdfminer库。