|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Oct 2011
Messaggi: 45
|
[java][PdfReader][OutOfMemoryError]Problemi nel leggere pdf di 500 mb o più
Salve, uso la classe PdfReader per leggere ed operare su dei pdf, ma dopo una certa dimensione del file mi da l'errore:
Codice:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.io.ByteArrayOutputStream.write(Unknown Source)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.InputStreamToArray(Rand
omAccessFileOrArray.java:209)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.<init>(RandomAccessFile
OrArray.java:199)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:237)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:248)
at code.Gestione.caricaPDF(Gestione.java:61)
at code.Start.main(Start.java:28)
Codice:
public void caricaPDF(FileInputStream pdf,String titolo) throws SQLException, IOException{
boolean protetto=false;
String nome=pulisciStringa(titolo);
if(isProcessato(nome)==0){
PdfReader lettore=null;
psf.setString(1, nome);
try{
lettore=new PdfReader(pdf);
psf.setInt(2, 0);
psf.setInt(3, 1);
psf.executeUpdate();
caricaTesto(lettore,getIdPDF(nome));
}catch (InvalidPdfException e){
psf.setInt(2, 1);
psf.setInt(3, 0);
psf.executeUpdate();
protetto=true;
}finally{
if(lettore!=null)
lettore.close();
}
Conoscete qualche tecnica o metodo per evitare ciò? Che so predividendo il file o usando un particolare metodo. Io qualcosa l'ho trovata ma nulla di che. Se serve altro codice chiedetelo, se avete proposte di ottimizzazione del metodo fatele.
__________________
Teo
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Non puoi caricare/leggere una pagina alla volta, o un tot di pagine alla volta? Non ho mai usato quella libreria, ma magari la sua API fornisca tale possibilità.
Se l'elaborazione che devi fare non richiede neccessariamente la presenza di tutto il contenuto del pdf in memoria ma puoi processarlo un po' per volta vai colpi di una, dieci, N o più pagine
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 08-03-2012 alle 14:43. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
@EDIT:
ho fatto una brevissima ricerca e pare che ci sia modo di fare delle "partial read" di un file pdf già esistente. Guarda questa pagina: contiene un sacco di esempi. In particolare la "partial read" l'ho vista qua (ma potrebbe non essere l'unico esempio ne il migliore). Insomma: devi sguazzare nella documentazione e/o forum/blog relativi dove potresti trovare info molto precise al rigurado
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Oct 2011
Messaggi: 45
|
Codice:
PdfReaderContentParser parser=new PdfReaderContentParser(lettore); parser.processContent(i,new SimpleTextExtractionStrategy()); String parole=pulisciStringa(PdfTextExtractor.getTextFromPage(lettore, i)); Però il problema sta nel momento della creazione del PdfReader (il lettore) purtroppo. Ho trovato questo link in cui una persona ha il mio stesso problema, ora vedo cosa posso ricavare, magari dacci un occhiata. http://itext-general.2136553.n4.nabb...td2146288.html
__________________
Teo
|
|
|
|
|
|
#5 | ||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Come nel link che ho postato sopra, guarda l'esempio della partial read (che poi è lo stesso sistema illustarto nel link che hai postato tu).
In pratica usando il costruttore di PdfReader che prende come argomenti un RandomAccessFileOrArray e null (per l'array di byte che rappresenta la user password, presumo per accedere a pdf protetti) vengono lette dallo stream del pdf solo le entità xref [qualunque cosa siano, non conosco le specifiche del formato pdf] e solo quando richieste. Link al javadoc @EDIT: 1) creare un PdfReader con un RandomAccessFileOrArray [come fin qua detto]. Quote:
Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 08-03-2012 alle 15:53. |
||
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Oct 2011
Messaggi: 45
|
con questa soluzione:
Codice:
public void caricaPDF(File f) throws SQLException, IOException {
boolean protetto=false;
String nome=pulisciStringa(f.getName());
if(isProcessato(nome)==0){
PdfReader lettore=null;
psf.setString(1, nome);
try{
lettore=new PdfReader(new RandomAccessFileOrArray(new FileInputStream(f)),null);
psf.setInt(2, 0);
psf.setInt(3, 1);
psf.executeUpdate();
caricaTesto(lettore,getIdPDF(nome));
}catch (InvalidPdfException e){
psf.setInt(2, 1);
psf.setInt(3, 0);
psf.executeUpdate();
protetto=true;
}finally{
if(lettore!=null)
lettore.close();
}
System.out.println("> Caricato nel database "+nome);
System.out.println("-Protetto= "+protetto);
System.out.println("-Pagine del pdf -> protette= "+protette+" vuote= "+vuote+" non inserite= "+nonInserite+" non convertite= "+nonConvertite);
}
else
System.out.println("> Preesistente nel database "+nome);
protette=0;
vuote=0;
nonInserite=0;
nonConvertite=0;
}
Codice:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.io.ByteArrayOutputStream.write(Unknown Source)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.InputStreamToArray(Rand
omAccessFileOrArray.java:209)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.<init>(RandomAccessFile
OrArray.java:199)
at code.Gestione.caricaPDF(Gestione.java:66)
at code.Start.main(Start.java:33)
__________________
Teo
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Il problema potrebbe essere nel modo in cui costruisci il RandomAccessFileOrArray: tu passi un FileInputStream, ma negli esempi io ho visto che viene passata solo la stringa che rappresenta il path del file. Oppure il problema è quello che ci fa con lettore il metodo caricaTesto, magari cerca di caricarlo tutto in memoria prima di fare quello che deve fare. Visto che tu già usi questa libreria ne saprai sicuramente più di chi non l'ha mai presa in mano: sono sicuro che se ti documenti a dovere sarai in grado di implementare la soluzione (la soluzione l'abbiamo già trovata: leggere e processare il file a pezzetti, non tutto intero).
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 09-03-2012 alle 11:26. |
|
|
|
|
|
|
#8 |
|
Member
Iscritto dal: Oct 2011
Messaggi: 45
|
Attualmente i creo il PdfReader e poi lo leggo e lo carico pagina per pagina. Devo trovare un metodo (come dicevi tu) funzionale per creare un reader di parte del file in modo tale da evitare l'eccezione, magari metto un controllo e nel momento in cui si verifica l'outofmemory frazionare il reader in parti. Ora vedo cosa trovo e ne posto i risultati in modo che possiate valutarli.
__________________
Teo
|
|
|
|
|
|
#9 | |
|
Member
Iscritto dal: Nov 2006
Messaggi: 201
|
Quote:
Guardando i costruttori sembra che sia proprio così come hai detto. Se si passa un InputStream viene caricato tutto in memoria, se si passa solo il path di default non viene caricato, oppure si può scegliere di sì : http://www.docjar.com/html/api/com/l...rray.java.html |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:51.




















