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
相关产品推荐
相关产品推荐

