2014-04-08 35 views
5

Sto provando a convertire la prima pagina di un file PDF in un'immagine utilizzando PDFBox. Quando carico un file pdf di grandi dimensioni ottengo un'eccezione.PDFbox caricamento di file di grandi dimensioni

codice:

PDDocument doc; 
    try { 
     InputStream input = new URL("http://www.jewishfederations.org/local_includes/downloads/39497.pdf").openStream(); 
     doc = PDDocument.load(input); 
     PDPage firstPage = (PDPage) doc.getDocumentCatalog().getAllPages().get(0); 
     BufferedImage image =firstPage.convertToImage(); 
     File outputfile = new File("image2.png"); 
     ImageIO.write(image, "png", outputfile); 
     input.close(); 
     doc.close(); 

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

eccezione:

org.apache.pdfbox.pdfparser.BaseParser parseCOSStream 
WARNING: Specified stream length 72435 is wrong. Fall back to reading stream until 'endstream'. 
org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 72435 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize 
    at org.apache.pdfbox.pdfparser.BaseParser.parseCOSStream(BaseParser.java:554) 
    at org.apache.pdfbox.pdfparser.PDFParser.parseObject(PDFParser.java:605) 
    at org.apache.pdfbox.pdfparser.PDFParser.parse(PDFParser.java:194) 
    at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1219) 
    at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1186) 
    at Worker.main(Worker.java:27) 
Caused by: java.io.IOException: Push back buffer is full 
    at java.io.PushbackInputStream.unread(Unknown Source) 
    at org.apache.pdfbox.io.PushBackInputStream.unread(PushBackInputStream.java:144) 
    at org.apache.pdfbox.io.PushBackInputStream.unread(PushBackInputStream.java:133) 
    at org.apache.pdfbox.pdfparser.BaseParser.parseCOSStream(BaseParser.java:550) 
    ... 5 more 
+0

Cosa succede quando si aumenta la dimensione del buffer push back? – azurefrog

+0

finora non ho trovato come farlo. – user2958571

+1

Il tuo messaggio di errore dice: 'Prova ad aumentare il buffer di pushback usando la proprietà di sistema org.apache.pdfbox.baseParser.pushBackSize' – azurefrog

risposta

2

primo luogo, trovare la dimensione del buffer corrente:

System.out.println(System.getProperty("org.apache.pdfbox.baseParser.pushBackSize")); 

Ora che avete una linea di base, fare esattamente quello che suggerisce. Aumentare la dimensione del buffer di sopra di quello appena stampato utilizzando questo:

System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "<buffer size>"); 

continuare ad aumentare la dimensione del buffer finché non funziona. Si spera che non si esaurisca la memoria, se si aumenta l'heap.

Ecco come si impostano le proprietà di sistema in fase di esecuzione. Potresti anche passarlo come argomento, ma trovo che l'impostazione vicino all'inizio di main farà il trucco e rende più facile per i futuri sviluppatori mantenere il progetto.

Per qualsiasi motivo, con file di grandi dimensioni non è disponibile un buffer sufficiente per caricare la pagina. Forse la pagina viene caricata in un buffer prima o durante il rendering in un'immagine. La mia ipotesi è che il DPI nel PDF sia molto alto e non possa essere inserito nel buffer.

+0

La tua risposta è perfetta eccetto per l'ultimo paragrafo. Nel parser "vecchio", il buffer di pushback viene utilizzato quando il flusso ha una lunghezza errata, ovvero il PDF non è corretto (il messaggio "La lunghezza specificata del flusso 72435 è errata"). In tal caso, il parser deve "tornare indietro" e la lunghezza predefinita pushbackbuffer è 65536, quindi "boom". –

+0

@guyfleeman Dove si trova l'elenco delle proprietà per pdfbox? – XY6

2

Una soluzione alternativa per le versioni PDF. * PDFBox è utilizzare il parser non sequenziale. In tal caso, il codice non sarebbe

doc = PDDocument.load(input); 

ma

doc = PDDocument.loadNonSeq(input, null); 

che parser (che sarà l'unico nella prossima versione 2.0) è indipendente dalla dimensione di un buffer pushback.

1

Avevo un problema simile, che pensavo fosse correlato a un grande file pdf basato sull'errore, tuttavia si è scoperto che non lo era. Si è rivelato un file pdf corrotto.

Per il nostro caso d'uso, abbiamo avuto un file modello pdf (che popola i suoi valori di forma a livello di codice) come una risorsa nel nostro progetto che viene cotta nella nostra guerra.

L'eccezione che stavo vedendo per riferimento: org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 480478 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize. Abbiamo aggiunto la proprietà e poi eseguito di nuovo le cose e abbiamo riscontrato un problema diverso.

La traccia dello stack successiva ha dichiarato "Impossibile leggere TTF incorporato per font TimesNewRoman, Bold". Ci è voluto un po ', tuttavia dopo aver fatto esplodere la guerra e aver provato ad aprire il file pdf in guerra, abbiamo notato che era corrotto, ma il file pdf che era in origine non era corrotto e poteva essere aperto senza problemi.

La causa principale del nostro problema era che abbiamo aggiunto "filtro" nel nostro pom per la nostra cartella delle risorse.Lo abbiamo fatto in modo da poter utilizzare alcuni riflessi per ottenere alcuni valori nella nostra pagina di controllo sanitario, ma questo ha danneggiato il file pdf, che abbiamo ricavato dal seguente riferimento: https://bitbucket.org/petermr/xhtml2stm/issues/12/pdf-files-are-being-corrupted-at-some

Di seguito è riportato un esempio del filtro che impostiamo che ci bit:

<resources> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>true</filtering> 
    </resource> 
</resources> 

la nostra soluzione era di rimuovere questo dalla nostra pom e rielaborare come siamo arrivati ​​le informazioni per la nostra pagina di salute.

Problemi correlati