Управление памятью iText - PdfReader / Watermarking загружает слишком много - PullRequest
1 голос
/ 16 августа 2011

Я ставлю водяные знаки на документы и не хочу загружать их полностью в память, поскольку они могут быть довольно большими. Я обнаружил, что RandomAccessFileOrArray такого рода буферизует чтение, что он делает хорошо, но все равно загружается слишком по моему вкусу.

То есть после загрузки PDF-файла объемом 5 МБ используемая память увеличивается на 23 МБ! И когда я начинаю ставить водяные знаки, он прыгает еще на 27 Мб! После этого используемая память постепенно увеличивается, но не ужасно.

Есть ли причина для такого поведения? Вы знаете способ определения размера буфера PdfReader или RandomAccessFileOrArray или что-то еще?

Спасибо за ваш вклад.


Метод printMem отображает состояние памяти, показывая свободное - использованное - общее.

Вот мой код

printMem("Before load");
    PdfReader reader = null;
    try {
        reader = new PdfReader(new RandomAccessFileOrArray(new FileInputStream("C:/TEMP/zip/100258.pdf")),null);
        printMem("After load");
        FileOutputStream out = new FileOutputStream(f);
        PdfStamper stamp = new PdfStamper(reader, out);

        int numPages = reader.getNumberOfPages();
        int page=1;
        BaseFont baseFont = 
            BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE,
                BaseFont.WINANSI, BaseFont.EMBEDDED);
        float width;
        float height;

        while (page <= numPages) {
            printMem("Page " + page);
            PdfContentByte cb = stamp.getOverContent(page);
            height = reader.getPageSizeWithRotation(page).getHeight() / 2;
            width = reader.getPageSizeWithRotation(page).getWidth() / 2;

            cb.saveState();
            cb.setColorFill(MEDIUM_GRAY);

            // Primary Text
            cb.beginText();
            cb.setFontAndSize(baseFont, PRIMARY_FONT_SIZE);
            cb.showTextAligned(Element.ALIGN_CENTER, "WatermarkText", width,
                    height, TEXT_TILT_ANGLE);
            cb.endText();

            cb.restoreState();
            page++;
        }
        stamp.close();
    } catch(Throwable e) {
        reader = null;
        System.gc();
    }

А вот частичный вывод:

Before load | 1566248160 6615840 1572864000
After load | 1542392472 30471528 1572864000
Page 1 | 1515096880 57767120 1572864000
Page 2 | 1515095992 57768008 1572864000
Page 47 | 1512998840 59865160 1572864000
Page 48 | 1512998840 59865160 1572864000

1 Ответ

3 голосов
/ 20 октября 2011

Документ будет прочитан только частично, если вы создадите RandomAccessFileOrArray со строкой, содержащей путь к файлу (например, new RandomAccessFileOrArray ("/ path / to / pdf");). При использовании InputStream или URL-адреса весь документ копируется во внутренний байтовый массив.

...