You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中使用PDFBox读取MultipartFile时getSize()在try-with-resources块内返回0的问题咨询

Spring Boot中使用PDFBox读取MultipartFile时getSize()在try-with-resources块内返回0的问题咨询

嘿,这个问题我之前也碰到过类似的情况,咱们来一步步拆解下:

为什么file.getSize()在try块里会变成0?

你猜的没错,核心原因就是输入流被消费了。当你创建RandomAccessReadBuffer(inputStream)的时候,这个构造方法会把输入流里的所有数据一次性读到内存缓冲区中,相当于把整个流“读干”了。

而你的MultipartFile实现(比如某些基于流式上传的自定义实现,或者特定场景下的Spring内置实现),它的getSize()方法并不是直接返回上传时就确定的元数据大小,而是会尝试从当前输入流中读取剩余的字节数。当流已经被读到末尾时,剩余字节数自然就是0,所以第二次调用getSize()就返回0了。

不过这里要补充一句:标准的SpringStandardMultipartFile其实是基于临时文件或者预先解析的元数据,getSize()不会因为流被读取而变化,但如果你的项目用了其他MultipartFile实现(比如自定义的、或者某些云存储适配的),就可能出现这个问题。

怎么可靠地获取文件大小?

最稳妥的做法就是在操作输入流之前,提前把文件大小缓存到变量里,之后全程用这个变量,不要再去调用file.getSize()了。

修改后的代码大概是这样:

public int getPageCount(MultipartFile file) throws IOException { 
    // 提前缓存文件大小,这时候流还没被消费,值是准确的
    long fileSize = file.getSize(); 
    try (InputStream inputStream = file.getInputStream(); 
         RandomAccessRead rar = new RandomAccessReadBuffer(inputStream); 
         PDDocument document = Loader.loadPDF(rar)) { 
        if (document.isEncrypted()) return -1; 
        // 这里直接用缓存好的fileSize,不用再调用file.getSize()
        System.out.println("文件大小:" + fileSize);
        return document.getNumberOfPages(); 
    } 
}

另外,还有个小建议:如果你的场景里文件可能很大,用RandomAccessReadBuffer把整个文件读到内存里可能会有OOM风险,这时候可以考虑用RandomAccessFile来基于临时文件操作,但这就需要先把MultipartFile转成临时文件再处理,不过这是另一个话题了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 14:43:02