iText7 (PDFSweep) выдает ошибку OutofMemory при редактировании большого PDF - PullRequest
0 голосов
/ 12 октября 2018

Я пытался удалить некоторое содержимое из PDF с помощью PDFSweep, ниже приведены части моего кода, я использую CompositeCleanupStrategy и добавляю RegexBasedCleanupStrategy в стратегию:

    CompositeCleanupStrategy strategy = new CompositeCleanupStrategy();
    for (int i = 0; i < keywordlist.size(); i++) {

        String kvalue = keywordlist.get(i);


        Loger.getLogger().info("keyword " + i + "=" + kvalue);

        strategy.add(new RegexBasedCleanupStrategy(kvalue).setRedactionColor(ColorConstants.GRAY));

    }

   try {
        PdfWriter writer = new PdfWriter(dest);
        writer.setCompressionLevel(0);
        PdfDocument pdf = new PdfDocument(new PdfReader(src), writer);
        // sweep
        PdfAutoSweep pdfAutoSweep = new PdfAutoSweep(strategy);

        pdfAutoSweep.cleanUp(pdf);

        // close the document
        pdf.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Когда страготы малы, как тамтолько один или два, очистка работает нормально, однако, если в списке ключевых слов есть 243, размер PDF составляет около 70 МБ, я получил следующую ошибку:

 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit 
 exceeded
at java.lang.String.toLowerCase(String.java:2590)
at java.lang.String.toLowerCase(String.java:2670)
at com.itextpdf.io.font.PdfEncodings.convertToString(PdfEncodings.java:287)
at com.itextpdf.kernel.pdf.PdfString.toUnicodeString(PdfString.java:163)
at com.itextpdf.kernel.pdf.canvas.parser.data.TextRenderInfo.getUnscaledBaselineWithOffset(TextRenderInfo.java:425)
at com.itextpdf.kernel.pdf.canvas.parser.data.TextRenderInfo.getBaseline(TextRenderInfo.java:213)
at com.itextpdf.kernel.pdf.canvas.parser.listener.CharacterRenderInfo.<init>(CharacterRenderInfo.java:112)
at com.itextpdf.kernel.pdf.canvas.parser.listener.RegexBasedLocationExtractionStrategy.toCRI(RegexBasedLocationExtractionStrategy.java:156)
at com.itextpdf.kernel.pdf.canvas.parser.listener.RegexBasedLocationExtractionStrategy.eventOccurred(RegexBasedLocationExtractionStrategy.java:135)
at com.itextpdf.pdfcleanup.autosweep.CompositeCleanupStrategy.eventOccurred(CompositeCleanupStrategy.java:115)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.eventOccurred(PdfCanvasProcessor.java:534)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.displayPdfString(PdfCanvasProcessor.java:549)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.access$4700(PdfCanvasProcessor.java:108)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor$ShowTextArrayOperator.invoke(PdfCanvasProcessor.java:617)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.invokeOperator(PdfCanvasProcessor.java:452)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.processContent(PdfCanvasProcessor.java:281)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.processPageContent(PdfCanvasProcessor.java:302)
at com.itextpdf.kernel.pdf.canvas.parser.PdfDocumentContentParser.processContent(PdfDocumentContentParser.java:77)
at com.itextpdf.kernel.pdf.canvas.parser.PdfDocumentContentParser.processContent(PdfDocumentContentParser.java:90)
at com.itextpdf.pdfcleanup.autosweep.PdfAutoSweep.getPdfCleanUpLocations(PdfAutoSweep.java:130)
at com.itextpdf.pdfcleanup.autosweep.PdfAutoSweep.cleanUp(PdfAutoSweep.java:186)

1 Ответ

0 голосов
/ 15 октября 2018

(полное раскрытие: оригинальный автор RegexBasedCleanupStrategy здесь)

RegexBasedCleanupStrategy не предназначено для использования таким образом.Вы создаете 200 экземпляров этого класса, каждый из которых будет проходить по документу, чтобы увидеть, могут ли они сопоставить (фрагмент за фрагментом) PDF-файл с регулярным выражением.

Для этого они сохранятвсе фрагменты в документе, отсортируйте их, а затем зациклите их.

Таким образом, вы дублируете документ 200 с лишним раз в памяти.Это ваше узкое место.

Мое предложение: создать лучшее регулярное выражение.Очевидно, вы можете сопоставить ключевое слово a, b, c и т. Д. С регулярным выражением

(a)|(b)|(c)

Это скопирует документ в памяти только один раз, а затем попытается сопоставить совокупное регулярное выражение с ним.

Обладает преимуществами как производительности, так и объема памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...