使用java一次阅读pdf uploadstream一页

时间:2009-02-25 14:49:08

标签: java pdf inputstream pdfbox

我正在尝试在j2ee应用程序中阅读pdf文档。

对于Web应用程序,我必须将pdf文档存储在磁盘上。为了便于搜索,我想在文档中制作文本的反向索引;如果是OCR。

使用PDFbox库可以创建包含整个pdf文件的pdfDocument对象。但是为了保留内存并提高整体性能,我宁愿将文档作为流处理,并一次将一页读入缓冲区。

我想知道是否可以逐页读取包含pdf的文件流,或者一次读取一行。

4 个答案:

答案 0 :(得分:1)

对于给定的通用pdf文档,您无法知道一个页面的结束位置和另一个页面的开始位置,至少使用PDFBox。

如果您关注的是资源的使用,我建议您将pdf文档解析为COSDocument,使用.getObjects()从COSDocument中提取已解析的对象,这将为您提供java.util.List。这应该很容易适应你拥有的任何稀缺资源。

请注意,您可以通过PDFBox API轻松将已解析的pdf文档转换为Lucene索引。

此外,在进入优化之前,请确保您确实需要它们。 PDFBox能够毫不费力地在相当大的PDF文档中进行内存表示。

要从InputStream解析PDF文档,请查看COSDocument

要编写lucene索引,请查看LucenePDFDocument class

对于COSDocuments的内存中表示,请查看FDFDocument

答案 1 :(得分:1)

在2.0。*版本中,打开PDF,如下所示:

PDDocument doc = PDDocument.load(file, MemoryUsageSetting.setupTempFileOnly());

这会将缓冲内存使用设置为仅使用没有限制大小的临时文件(无主内存)。

回答here

答案 2 :(得分:-1)

查看PDF Renderer Java库。我自己尝试过,看起来比PDFBox快得多。但是,我没有尝试过获取OCR文本。

以下是从上面的链接复制的示例,其中显示了如何将PDF页面绘制到图像中:

    File file = new File("test.pdf");
    RandomAccessFile raf = new RandomAccessFile(file, "r");
    FileChannel channel = raf.getChannel();
    ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
    PDFFile pdffile = new PDFFile(buf);

    // draw the first page to an image
    PDFPage page = pdffile.getPage(0);

    //get the width and height for the doc at the default zoom 
    Rectangle rect = new Rectangle(0,0,
            (int)page.getBBox().getWidth(),
            (int)page.getBBox().getHeight());

    //generate the image
    Image img = page.getImage(
            rect.width, rect.height, //width & height
            rect, // clip rect
            null, // null for the ImageObserver
            true, // fill background with white
            true  // block until drawing is done
            );

答案 3 :(得分:-2)

我想你可以逐字节地读取文件,寻找分页符。由于可能存在PDF格式问题,逐行更难。