使用Java itext库为大文件崩溃签名PDF

wol*_*ePk 2 java exception itext digital-signature

我使用Itext库进行PDF签名,适用于50MB以下的小文件.但是如果文件大小为150MB那么大小的文件就会崩溃

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at com.itextpdf.text.pdf.ByteBuffer.append(ByteBuffer.java:210)
at com.itextpdf.text.pdf.ByteBuffer.write(ByteBuffer.java:622)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at com.itextpdf.text.pdf.OutputStreamCounter.write(OutputStreamCounter.java:104)
at com.itextpdf.text.pdf.PRStream.toPdf(PRStream.java:230)
at com.itextpdf.text.pdf.PdfIndirectObject.writeTo(PdfIndirectObject.java:157)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.write(PdfWriter.java:397)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:386)
at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:848)
at com.itextpdf.text.pdf.PdfStamperImp.close(PdfStamperImp.java:353)
at com.itextpdf.text.pdf.PdfStamperImp.close(PdfStamperImp.java:327)
at com.itextpdf.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:1244)
at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:134)
Run Code Online (Sandbox Code Playgroud)

这是我的签名代码,适用于少于50 MB的pdf文件

     private void PdfSigningProcess(String src, String dest,
        Certificate[] chain,
        PrivateKey pk, String digestAlgorithm, String provider,
        MakeSignature.CryptoStandard subfilter, String reason, String location)
        throws
        GeneralSecurityException, IOException, DocumentException
  {
    // Creating the reader and the stamper
    PdfReader reader =
            new PdfReader(src);
    FileOutputStream os =
            new FileOutputStream(dest);
    PdfStamper stamper = PdfStamper.
            createSignature(reader, os, '\0');
    //Creating the appearance PdfSignature Appearance
    PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
    appearance.setReason(reason);
    appearance.setLocation(location);
    appearance.setVisibleSignature(new Rectangle(36, 7, 48, 144, 780), 1, "DQCA Signature");
    // Creating the signature 
    ExternalDigest digest = new BouncyCastleDigest();
    ExternalSignature signature =
            new PrivateKeySignature(pk, digestAlgorithm, provider);
    MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter); //HERE IT IS CRASHING
}
Run Code Online (Sandbox Code Playgroud)

"MakeSignature.signDetached"这是异常来临的函数...请指导我如何解决这个问题,因为写入和追加过程是在这个函数里面,我不能改变并逐行刷新数据...

Bru*_*gie 5

我看到你已经阅读了我的白皮书,但我也看到你选择在内存中签署文件.正如Michaël所说,如果你要求iText使用大量内存,你不应该责怪iText使用大量内存;-)

请阅读标题为"签署大型PDF文件"的第2.2.4节.在该部分中,您将找到一个示例,说明如何使用临时文件进行签名.这将显着减少内存使用.

不要忽视注:如果您使用的createSignature()方法有一个临时文件,你可以使用一个OutputStream就是null,在这种情况下,临时文件将作为实际的目标文件.如果您的目标是在文件系统上存储已签名的文件,这是一种很好的做法.如果OutputStream不是null,iText将始终在签名完成后尝试删除临时文件.