Читайте поток загрузки pdf по одной странице за раз с помощью java

Я пытаюсь прочитать PDF-документ в приложении j2ee.

Для веб-приложения мне нужно хранить PDF-документы на диске. Чтобы упростить поиск, я хочу сделать обратный индекс текста внутри документа; если это OCR.

С помощью библиотеки PDFbox можно создать объект pdfDocument, который содержит весь файл pdf. Однако, чтобы сохранить память и улучшить общую производительность, я бы предпочел обрабатывать документ как поток и читать по одной странице в буфер.

Интересно, можно ли читать поток файлов, содержащий pdf страницу за страницей или даже по одной строке за раз.

Ответов (4)

Я полагаю, вы можете читать файл побайтно, ища разрывы страниц. Построчно сложнее из-за возможных проблем с форматированием PDF.

Для данного общего PDF-документа у вас нет возможности узнать, где заканчивается одна страница и начинается другая, по крайней мере, с помощью PDFBox.

Если вас беспокоит использование ресурсов, я предлагаю вам преобразовать PDF-документ в COSDocument, извлечь проанализированные объекты из COSDocument, используя .getObjects (), что даст вам java.util.List. Это должно быть легко вписаться в те ограниченные ресурсы, которые у вас есть.

Обратите внимание, что вы можете легко преобразовать проанализированные PDF-документы в индексы Lucene через API PDFBox.

Кроме того, прежде чем окунуться в мир оптимизаций, убедитесь, что они вам действительно нужны. PDFBox может без особых усилий создавать в памяти представление довольно больших PDF-документов.

Чтобы разобрать PDF-документ из InputStream, посмотрите на класс COSDocument

Для написания индексов Lucene посмотрите класс LucenePDFDocument

Для представления COSDocuments в памяти см. FDFDocument

Взгляните на библиотеку Java PDF Renderer . Я сам пробовал, и кажется, что он намного быстрее, чем 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
            );

В версиях 2.0. * Откройте PDF-файл следующим образом:

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

Это настроит использование буферной памяти для использования только временных файлов (без основной памяти) без ограничения размера.

На это был дан ответ здесь .