【问题标题】:Cannot read file via docker container无法通过 docker 容器读取文件
【发布时间】:2019-07-27 23:58:21
【问题描述】:

我有一个 spring-boot 应用程序,我有一些文件放在 /src/main/java/resources 中,我试图在我的代码中读取它。当相同的代码尝试从 docker 容器中读取时,它说文件不存在。相同的代码通过 localhost 可以正常工作

文件位于 /src/main/java/resources/data 文件夹下,这是我尝试读取文件的代码

 private String getJson(String folderName, String id, StringBuilder sb) throws Exception {
        String responseJson = null;
        String filePath = "data" + File.separator + folderName + File.separator + id + ".json";
        LOG.info("printing filePath : " + filePath);
        LOG.info("printing id : " + id);
        File f = new File(filePath);
       // if(f.exists()){
            try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
                LOG.info("printing inputStream : " + inputStream);
                if (inputStream != null) {
                    responseJson = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
                }
                if (responseJson == null || responseJson.isEmpty()) {
                    LOG.info("json response is null : ");
                    throw new JsonNotFoundException(Constant.JSON_NOT_FOUND);
                }
                sb.append(responseJson);
            } catch (IOException e) {
                LOG.info("IO exception : ");
                throw new IOException(e);
            } catch (Exception e) {
                LOG.info(" exception : ");
                throw new Exception(e);
            }
//        }
//        else{
//            LOG.info("file doesnt exists : " + filePath);
//        }
        return sb.toString();
    }

文件路径示例:src/main/resources/data/get-products/1420-17612-82.json Docker 文件内容

{
  "commands":
  [
    "rm -rf .tmp",
    "git clone git@github.com:{orgnname}/{test-service.git} -b COECP-973-Configure-logging-mechanism-for-Service .tmp/test-service",
    "docker build .tmp/test-service/.docker/build/db -t local/test-service/db",
    "docker build .tmp/test-service -t local/test-service/app"
  ]
}

【问题讨论】:

  • 如何编译和运行应用程序?容器是否甚至可以访问src?即使没有 Docker,Java 应用程序通常也会被编译成 jar 文件,在部署后不会显示其源代码,您必须从类加载器加载资源,而不是从文件系统加载。
  • 好的。在 /classes/data 下编译后它们位于我的类路径中,我正在尝试通过类加载器加载它们
  • 所以我编辑了我的问题并附上了完整的源代码
  • 对不起 /src/main/resources 是正确的路径。另外,在问题中添加 dockerfile 内容。
  • 是的,它是 /src/main/java/resources

标签: java spring-boot docker docker-compose


【解决方案1】:

我之前也遇到过同样的问题,虽然随着时间的推移我们的要求变得越来越复杂,但是下面的代码应该可以解决你的问题:

    ClassPathResource cp = new ClassPathResource("relative_path_to_file");
    File f = null;

    if (cp.exists())
        f = cp.getFile();

【讨论】:

  • 这个有效,我使用的是 ItextPdf 库,它需要绝对路径(不是实际文件)。 cp.getFile().getAbsolutePath() 也是如此。
  • 这是ClassPathResource 一个特殊的库类吗?
【解决方案2】:

所以...您弄乱了 File 和类路径中的资源的路径。有File f = new File(filePath); 的原因是什么?

这里有一些事情:

  1. 如果您使用 File - 文件必须对 JVM 可用,并且只要您使用像 data\folderxxx\filexxx.json 这样的相对路径,它必须在容器文件系统中可用。 IE。 data 文件夹必须放在镜像中或从外部完全安装到 JVM 运行的目录中

  2. 如果您使用ClassLoaderResourceAsStream,您的data 目录的根必须在JVM 的类路径中定义或在Jar 文件中 - 它也是类路径中的根。检查您的 jar 文件 - 如果 data 目录位于 jar 的根目录中 - 一切正常,文件将由 this.getClass().getClassLoader().getResourceAsStream(filePath) 提供,但不适用于 new File(filePath)

如果没有 - 让它发生或相应地更新 ResourceAsStream 的 filePath。

【讨论】:

  • 是的,这被 new File() 搞砸了。我刚刚删除它,它就可以工作了
猜你喜欢
  • 2018-09-07
  • 2021-10-10
  • 1970-01-01
  • 2022-06-29
  • 2018-10-12
  • 2019-11-02
  • 2020-03-11
  • 2021-12-24
  • 2021-05-16
相关资源
最近更新 更多