Ошибка вывода текста из памяти при чтении PDF (Android)

#java #android #pdf #out-of-memory #itext

#java #Android #PDF #нехватка памяти #itext

Вопрос:

У меня есть файл размером ~ 5 МБ, который я хочу прочитать с помощью iText. Моя цель — наложить многие страницы из этого PDF-файла на другой PDF.

Это мой код :

 try {               
    AssetManager assetManager = getActivity().getAssets();
    InputStream istr = null;
    PdfReader reader = null;
    istr =(InputStream) assetManager.open("chem.pdf");
    reader=new PdfReader(istr);  
    Document document = new Document();
    PdfWriter writer=  PdfWriter.getInstance(document, new FileOutputStream(Environment.getExternalStorageDirectory()  "/pdfpdfpdfpdfpdf.pdf"));
    document.open();
    document.add(new Paragraph("                                                          Generated By Harshvardhan Gupta"));
    document.newPage();
    PdfContentByte canvas = writer.getDirectContent();
    PdfImportedPage page;
    //Rectangle r=document.getPageSize();
    float pos=720;
    float CurPsize=0; 
    float counter=0;
    float oldc=0;
    //r.getBottom();
    for(int m=1;m<35;m  ,counter  ) {
        page = writer.getImportedPage(reader, m);
        Rectangle r=reader.getPageSize(m);
        CurPsize= (r.getTop()-r.getBottom());
        pos=pos-CurPsize;
        Rectangle q=reader.getPageSize(m 1); 
        int mq=(int) (q.getTop()-q.getBottom());
        if(pos<mq counter*25 50){
            document.newPage();
            pos=720;
            counter=0;
        }
        canvas.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
        canvas.addTemplate(page, 1f, 0, 0, 1,100,pos-70-counter*25);
        BaseFont bf= BaseFont.createFont();
        canvas.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
        canvas.beginText();
        canvas.setFontAndSize(bf,14);
        canvas.setTextMatrix(75, (float) ((float) (pos-70-counter*25)-10 CurPsize));
        canvas.setLineWidth(0.5f);
        canvas.showText(m "." " ");
        canvas.endText();
    }
    document.close();
    writer.freeReader(reader);
    writer.close();
    reader.close();
    //spinner.setVisibility(View.INVISIBLE);
    Log.d("OK", "done");
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (DocumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
//spinner.setVisibility(View.INVISIBLE);
  

Происходит довольно много всего, но я думаю, что ошибка OutOfMemoryError возникает еще до того, как PDF-файл считывается из ресурсов.

Это полный журнал ошибок:

 06-21 19:39:12.090: E/AndroidRuntime(6844): FATAL EXCEPTION: main
06-21 19:39:12.090: E/AndroidRuntime(6844): java.lang.OutOfMemoryError
06-21 19:39:12.090: E/AndroidRuntime(6844):     at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.FlateDecode(PdfReader.java:2004)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.FlateDecode(PdfReader.java:1859)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.FilterHandlers$Filter_FLATEDECODE.decode(FilterHandlers.java:107)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.decodeBytes(PdfReader.java:2409)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.decodeBytes(PdfReader.java:2357)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.getStreamBytes(PdfReader.java:2422)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.readObjStm(PdfReader.java:1363)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.readDocObj(PdfReader.java:1305)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.readPdf(PdfReader.java:649)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:187)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:328)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:349)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.mainpackage.FragmentOne$1.onClick(FragmentOne.java:88)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at android.view.View.performClick(View.java:3511)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at android.view.View$PerformClick.run(View.java:14105)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at android.os.Handler.handleCallback(Handler.java:605)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at android.os.Handler.dispatchMessage(Handler.java:92)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at android.os.Looper.loop(Looper.java:137)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at android.app.ActivityThread.main(ActivityThread.java:4424)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at java.lang.reflect.Method.invokeNative(Native Method)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at java.lang.reflect.Method.invoke(Method.java:511)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:592)
06-21 19:39:12.090: E/AndroidRuntime(6844):     at dalvik.system.NativeStart.main(Native Method)
  

Обратите внимание, что я попытался использовать файл меньшего размера (200 КБ), и он работает. Означает ли это, что я не могу прочитать такой большой файл на Android с помощью iText?

Комментарии:

1. Какую версию вы используете? Можете ли вы поделиться своим PDF-файлом?

Ответ №1:

В моем PDF-файле было много аннотаций с использованием инструмента «Перо». Это было причиной проблемы. Я удалил метки пера, и pdf загружается нормально.

Комментарии:

1. Таким образом, по существу (полностью расширенное) содержимое вашего файла слишком велико. Если вы не можете вырезать PDF, альтернативой может быть частичная загрузка.

2. о? Не могли бы вы сказать мне, как загрузить его частично? Если я хочу загрузить, скажем, страницу x, y, z, то как мне это сделать?

3. как загрузить его частично PdfReader конструктор, принимающий a RandomAccessFileOrArray , работает в частичном режиме, см. его комментарии JavaDoc.

4. @harveyslash в моем случае пользователь может выбрать любой PDF-файл, поэтому, не внося никаких изменений в файлы PDF, возможно ли исправить эту проблему с ООМ?