java-pdfbox/itextpdf出现too many open files

近期项目中多线程处理pdf文件时,代码跑一段时间就会抛异常too many open files

通过 lsof -p 端口号 | wc -l 命令查看项目进程发现打开文件数量一直在网上涨,后根据异常发现处理pdf文件代码有问题,其中有获取pdf文件内容和分割单个pdf文件成多个文件的方法会出现异常。

通过排查发现分割pdf中PdfReader读取完成后没有执行.close,一直没有关闭,导致句柄数一直增长而报错。

如果不是强需求可以修改linux配置增大打开文件数:

vim /etc/security/limits.conf  
#文件末尾加入以下两行 设置最大65536
* soft nofile 65536
* hard nofile 65536

 

而我是写代码粗心问题,以下是修改后的代码:

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.PDFTextStripperByArea;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;

public class PDFUtil {

    /**
     * 获取pdf文件内容 排除20k以下大小文件
     * @param file
     * @return
     * @throws IOException
     */
    public static String getPDFText(File file) throws IOException {
        if(file.exists()){
            long size = file.length()/1024;
            if(size>20 && check(file.getPath())){
                PDDocument document = null;
                try {
                    document = PDDocument.load(file);
                    if (!document.isEncrypted()) {
                        PDFTextStripperByArea stripper = new PDFTextStripperByArea();
                        stripper.setSortByPosition(true);
                        PDFTextStripper tStripper = new PDFTextStripper();
                        String pdfFileInText = tStripper.getText(document);
                        return pdfFileInText;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(document!=null){
                        document.close();
                    }
                }
            }
        }
        return null;
    }

    /**
     * 截取pdfFile的第from页至第end页,组成一个新的文件名
     *
     * @param pdfFile 要切割的pdf文件
     * @param newFile 切割后形成的新的pdf文件
     * @param from    从第N页开始
     * @param end     到第N页结束
     */
    public static void partitionPdfFile(String pdfFile, String newFile, int from, int end) {
        Document document = null;
        PdfCopy copy = null;
        PdfReader reader = null;
        try {
            File fileSource = new File(pdfFile);
            if(fileSource.exists() && check(pdfFile)){
                reader = new PdfReader(pdfFile);
                int n = reader.getNumberOfPages();
                if(n<=2){
                    File file = new File(newFile);
                    if(!file.exists()){
                        PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(newFile)) ;
                        stamper.close() ;
                        reader.close() ;
                    }
                }else{
                    System.out.println(pdfFile+"+page+"+n);
                    if (end == 0) {
                        end = n;
                    }
                    document = new Document(reader.getPageSize(1));
                    copy = new PdfCopy(document, new FileOutputStream(newFile));
                    document.open();
                    for (int j = from; j <= end; j++) {
                        document.newPage();
                        PdfImportedPage page = copy.getImportedPage(reader, j);
                        copy.addPage(page);
                    }
                    document.close();
                    copy.close();
                }
            }
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }finally {
            if(reader!=null){
                reader.close();
            }
        }
    }

    public static boolean check(String file) {
        boolean flag1 = false;
        int n = 0;
        try {
            PdfReader reader = new PdfReader(file);
            Document document = new Document(reader.getPageSize(1));
            document.open();
            n = reader.getNumberOfPages();
            if (n != 0){
                flag1 = true;
            }
            reader.close();
            document.close();
        } catch (Exception e) {
            File file1 = new File(file);
            file1.delete();
        }
        return flag1;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值