通过Docker容器无法读取文件

3

我有一个Spring Boot应用程序,其中一些文件放置在/src/main/java/resources中,我正在尝试在我的代码中读取它们。当同样的代码尝试从Docker容器中读取时,它会显示文件不存在。通过本地主机,相同的代码可以完美地工作。

这些文件位于/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 文件,在部署后就不再具有其源代码,并且需要从 classloader 而不是文件系统加载资源。 - Thilo
好的。编译后,它们在我的类路径下的/classes/data目录中,我正在尝试通过类加载器加载它们。 - Vinaya Nayak
所以我编辑了我的问题,并附上了完整的源代码。 - Vinaya Nayak
1
抱歉,/src/main/resources 是正确的路径。此外,请在问题中添加Dockerfile内容。 - ilinykhma
是的,它在 /src/main/java/resources 目录下。 - Vinaya Nayak
2个回答

1
所以...您弄错了文件路径和类路径资源。为什么要使用File f = new File(filePath);
以下是需要注意的事项:
  1. 如果使用File,则文件必须对JVM可用,只要使用相对路径,例如data\folderxxx\filexxx.json,它必须在容器文件系统中可用。也就是说,data文件夹必须放置在映像中或从外部挂载到JVM运行的目录中。

  2. 如果使用ClassLoaderResourceAsStream,则data目录的根目录必须在JVM的类路径中定义或在Jar文件中 - 它也是类路径中的根目录。检查您的jar文件 - 如果data目录位于jar的根目录中,则所有文件都可以通过this.getClass().getClassLoader().getResourceAsStream(filePath)访问,但不能使用new File(filePath)

如果不是这样,请使其发生或相应地更新ResourceAsStream的filePath。

是的,使用 new File() 函数出了问题。我刚刚将其删除后,代码就正常工作了。 - Vinaya Nayak

1

我之前也遇到过同样的问题,尽管我们的需求随着时间变得更加复杂,但以下代码应该可以解决你的问题:

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

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

这个可以,我正在使用ItextPdf库,并且它需要绝对路径(而不是实际文件)。所以我执行了cp.getFile().getAbsolutePath()。 - Gurkha
这个 ClassPathResource 是一个特殊的库类吗? - Niko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接