使用Spring RestTemplate上传文件时出现java.io.FileNotFoundException报错
问题根因
- 路径解析错误:你构造的
/C:/../../promoCode/路径包含无效的前置斜杠和上级目录回退符,Spring会将该路径误识别为类路径资源进行读取,而非读取本地磁盘路径的文件,最终触发文件不存在异常。 - 流操作逻辑错误:文件写入完成后未主动flush缓冲区就直接读取,且未使用安全的资源关闭逻辑,可能导致文件内容未完全写入磁盘、文件句柄被占用无法读取的问题。
- 文件上传构造逻辑不规范:仅读取文件第一行内容作为上传体,且手工构造表单参数的逻辑冗余,不符合RestTemplate处理multipart表单上传的标准实现。
解决方案
按以下步骤修复即可解决异常:
- 修正本地文件路径,指定明确的可访问目录,提前创建目标目录避免写入失败
- 采用try-with-resources语法自动管理文件流,写入完成后再执行读取上传逻辑
- 改用
FileSystemResource封装本地文件,直接作为multipart表单的file参数提交,简化构造逻辑
修复后参考代码:
// 1. 修正路径,指定明确的存储目录,不要用相对回退和冗余前置斜杠 String dirPath = "C:/promoCode/"; // 提前创建目录,避免写入失败 File dir = new File(dirPath); if (!dir.exists()) { dir.mkdirs(); } String filePath = dirPath + fileName + ".txt"; File targetFile = new File(filePath); // 2. 用try-with-resources自动关闭流,确保内容完全写入磁盘 try (BufferedWriter buffer = new BufferedWriter(new FileWriter(targetFile))) { buffer.write(generatedVoucherText); buffer.flush(); } catch (IOException e) { // 自行处理写入异常 e.printStackTrace(); return; } String bucketName = "promocodes"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 3. 直接用FileSystemResource封装文件,RestTemplate会自动处理表单参数 MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); body.add("file", new FileSystemResource(targetFile)); HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(body, headers); minioService.postMinio2(httpEntity, bucketName); // 可选:上传完成后删除本地临时文件 // targetFile.delete();
优化建议
如果不需要保留本地临时文件,可以直接把生成的文本内容转成字节数组封装为ByteArrayResource上传,省去本地磁盘读写的步骤,性能更高:
ByteArrayResource resource = new ByteArrayResource(generatedVoucherText.getBytes(StandardCharsets.UTF_8)) { @Override public String getFilename() { return fileName + ".txt"; } }; body.add("file", resource);
内容的提问来源于stack exchange,提问作者mark whalf
相关产品推荐
相关产品推荐

