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

Java项目部署Heroku后存储文件提示找不到路径如何解决?

问题描述

我编写了一个通过MultipartFile存储logo图片的相关方法,本地环境运行完全正常,但将项目部署到Heroku云平台托管时出现报错。

Heroku控制台报错日志

2021-10-31T08:38:33.118740+00:00 app[web.1]: 2021-10-31 08:38:33.118  INFO 4 --- [io-47772-exec-9] com.Indoera.ecomProject.Utils.Utils      :  org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@60241167

2021-10-31T08:38:33.118885+00:00 app[web.1]: java.io.IOException: No such file or directory

2021-10-31T08:38:33.119038+00:00 app[web.1]:    at java.io.UnixFileSystem.createFileExclusively(Native Method)

报错相关代码

public static String storeLogoPath(MultipartFile file) {
        String path = "";
        try {
            path = "G:/MainWorkSpace/TestProjects/ecomProject/src/main/resources/static/img/storeLogo/"+file.getOriginalFilename();
            File newFile = new File(path);
            newFile.createNewFile();
            FileOutputStream myfile = new FileOutputStream(newFile);
            myfile.write(file.getBytes());
            path ="/img/storeLogo/"+file.getOriginalFilename(); //PAth is setted mannualy to display images 
            myfile.close();
            logger.info("File should be saved now :: ");
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("Path Returned is ::: "  + path);
        return path;
    }
解决方案

你已经定位到核心原因是硬编码的Windows本地绝对路径在Heroku的Linux环境下不存在,除此之外还要注意Heroku的文件系统是临时可写的,所有写入的文件会在dyno重启、重新部署时自动清空,因此分两种场景给出解决方案:

1. 临时测试用方案(不适用生产环境)

放弃硬编码绝对路径,改为获取运行时目录,同时新增父目录存在性校验,修改后的代码示例如下:

public static String storeLogoPath(MultipartFile file) {
    String returnPath = "";
    // 获取项目运行时的工作目录,拼接静态资源存储路径
    String baseDir = System.getProperty("user.dir") + "/src/main/resources/static/img/storeLogo/";
    try {
        File dir = new File(baseDir);
        // 父目录不存在则先递归创建
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String fullPath = baseDir + file.getOriginalFilename();
        File newFile = new File(fullPath);
        newFile.createNewFile();
        // 使用try-with-resources自动关流,避免异常场景流泄漏
        try (FileOutputStream myfile = new FileOutputStream(newFile)) {
            myfile.write(file.getBytes());
        }
        returnPath = "/img/storeLogo/" + file.getOriginalFilename();
        logger.info("File should be saved now :: ");
    } catch (Exception e) {
        e.printStackTrace();
    }
    logger.info("Path Returned is ::: "  + returnPath);
    return returnPath;
}

注意:该方案仅能临时解决报错,Heroku重启后所有上传的图片会丢失。

2. 生产可用方案

不要将上传的图片存储在Heroku服务器本地,改为存储到专门的对象存储服务中,流程如下:

  • 开通任意对象存储服务,获取访问密钥
  • 上传文件时直接将文件流提交到对象存储服务
  • 存储服务返回可访问的图片公网链接,将该链接存入数据库即可
    该方案不受Heroku临时文件系统限制,数据永久可访问。

内容的提问来源于stack exchange,提问作者shivam sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:06:04