【问题标题】:java - How to have a resource filejava - 如何拥有资源文件
【发布时间】:2019-08-17 21:22:12
【问题描述】:

(我是java新手,请谅解)

我正在用 java 编写一个需要配置文件的应用程序,配置文件是一个 json 文件,我需要打开它并读取它的内容,但无论我如何尝试我都无法做到,我已经做了几个小时的查找在互联网上,但我找不到工作方式

我尝试使用我的 POM.xml 创建资源文件夹,然后使用 .getResource() 但这似乎不起作用

我的 java

public class MusicOrganizer {

    public static String configURL = "assets/config.json";
    public static String configSource;

    public static void main(String[] args) {

        try {

            configSource = MO.getFileFromResources(configURL);

        } catch (IOException e) {

            // This isn't what is going wrong

            System.out.println("Error reading config file!\n" + e + "\nDisplaying error screen...");

            errorScreen.main("Error Reading Config", "Try redownloading the application.","ERC_001");

            return;

        }

    }

    private String getFileFromResources(String fileName) throws IOException {

        ClassLoader classLoader = getClass().getClassLoader();

        URL resource = classLoader.getResource(fileName);
        if (resource == null) {
            throw new IllegalArgumentException("file is not found!"); // this is what is going wrong
        } else {
            return printFile(new File(resource.getFile()));
        }

    }

    private static String printFile(File file) throws IOException {

        if (file == null) throw new IllegalArgumentException("file is not found!");

        String source = "";

        try (FileReader reader = new FileReader(file);
             BufferedReader br = new BufferedReader(reader)) {

            String line;
            while ((line = br.readLine()) != null) {
                source += line;
            }

            return source;
        }
    }

}

我在其中创建“资源文件夹”的 POM.xml

<build>
     <resources>
        <resource>
            <directory>assets</directory>
        </resource>
     </resources>
</build>

请告诉我我做错了什么,我想让我的 java 文件(以压缩的 .jar 形式)读取“config.json”文件中的内容。

我使用的是 NetBeans 11.1,java 版本“12.0.2”2019-07-16, Java(TM) SE 运行时环境 (build 12.0.2+10), Java HotSpot(TM) 64 位服务器 VM(内部版本 12.0.2+10,混合模式,共享)和 MacBook Pro

我的目录路径:


>ROOT
  >nb-configuration.xml
  >nbactions.xml
  >pom.xml
  >src
    >main
      >java
        >com
          >[my name]
            >musicorganizer
              [java files]
        >JSON
          [java files]
      >resources
        config.json
    >test
      >java
        [nothing here]
  >target
    [Stuff]

【问题讨论】:

  • 如果它在 JAR 中,则需要使用 getResourceAsStream():stackoverflow.com/questions/20504014/… 和 stackoverflow.com/questions/3861989/…
  • 无法通过通常的文件 API 读取资源(例如 File)。要读取资源的内容,您需要通过#getResource(String) 返回的URL 或直接通过#getResourceAsStream(String) 打开一个InputStream。此外,不需要添加资源根目录——只需使用标准的默认目录(即src/main/resources)。至于找不到资源,你的目录结构是什么样的?
  • 我添加了我的目录结构
  • 您首先需要明确自己想要什么。您想要一个只读的、不可编辑的资源嵌入到您的构建生成的 jar 文件中,还是想要一个用户或程序可以编辑以更改配置的外部、可编辑的配置文件?如果是前者,请使用位于 src/main/resources 中的资源,并使用 MyClass.class.getResourceAsStream("/thefile.json") 读取它。否则,不要将其作为资源。例如,将其设为位于用户主目录下的文件,并使用文件 IO 对其进行读/写。
  • 那么它应该是一个资源。它应该是文件系统上的普通旧文件。不要尝试使用 Maven 将其嵌入到 jar 中,因为您不希望这样。

标签: java maven netbeans


【解决方案1】:

一般来说,除非你有充分的理由,否则你可能不需要覆盖 maven 的默认配置。

Maven 使用“约定优于配置”的理念,即:

  • 为属性假定合理的默认值
  • 允许您在需要时覆盖它

所以,如果你想要一个资源文件夹,maven默认为你提供了一个(假设你遵循默认的项目结构)

您应该在src/main/resources 有一个资源文件夹,您的Java 代码在src/main/java/&lt;package-name&gt;。这是 maven 期望的默认结构。

从那里您可以使用Class.getResource() 获得对此的引用。例如,如果您在src/main/resources/file.txt 中有一个文件,您可以使用getClass().getResource("/file.txt") 访问它(注意前导斜杠)。

但是,如果您想在运行时修改它(也许如果用户想保存新的详细信息),您不应该使用资源。相反,请考虑以下其中一项:

  • 当前目录中的文件 - 只需使用 new File("config.txt") 并读取/写入该文件
  • 用户主目录中的文件 - 使用 new File(System.getProperty(user.home), "config.txt")。例如,在 Windows 上,这会在 C:/users/&lt;username&gt;/config.txt 创建一个文件。
  • 数据库 - 如果您的应用程序已经使用数据库,它可能是存储大量配置选项的好地方,但根据您的问题,我想这不适合您。

【讨论】:

  • getClass().getResource("/config.json") 返回一个 url,而不是文件内容,我如何从中获取文件内容?
  • 如果我这样做,我会得到no suitable constructor found for File(URL)
  • 我错了,你需要拨打new File(getClass().getResource("/config.txt").getFile())
  • @cameron1024 从不调用 URL 的 getFile() 方法。它不返回有效的文件名!它只返回 URL 的路径部分,其中可能包含许多不允许直接出现在 URL 中的字符的百分比转义。此外,如果 URL 不是 file: URL,则该路径无论如何都不能用作文件名。读取 URL 的唯一正确方法是打开它,例如使用其 openStream 方法。
  • 明白了——出于好奇,你知道 'getFile()` 的预期目的是什么吗?
猜你喜欢
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2015-10-12
相关资源
最近更新 更多