当前位置: 首页 > 知识库问答 >
问题:

从与JAR文件相同的文件夹中读取文件,但从IDE加载时仍读取资源文件夹

史英睿
2023-03-14

我一直在尝试制作可以读取与它相同目录中的csv文件的jar应用程序。然而,事实证明这很困难,因为我目前访问该文件的方法是:

InputStream is = getClass().getClassLoader().getResourceAsStream(filename);

它适用于在IDE中运行的程序和测试,但在从编译的jar文件运行程序时不起作用。我不知道如何让它对这两者都起作用。我真的不能理解这个路径的东西,似乎有一百万种方法可以做到这一点,其中只有一种只适用于一个特定的场景。

共有1个答案

公孙涵育
2023-03-14

我一直在尝试制作一个jar应用程序,它可以读取与之相同目录中的csv文件。

啊,这就是你的问题。这不是一件事。

只有2种类型的文件:

这些文件是只读的,与类文件一样,它们也是应用程序的一部分。考虑“编辑”它们在任何方面都不相关——它们不是这样的事情。可以合理地假设,如果该资源不知何故丢失,应用程序就会像类文件丢失一样损坏/错误安装。

为此,请使用。获取资源和代码。getResourceAsStream(获取资源流)。请注意,getClass()。getClassLoader()错误,您需要MyClass。班如果您想从根目录开始,请使用getResource,然后添加斜杠(因为当您子类化时,getClass()可能会中断,而通过classloader只是无缘无故地键入,而在引导加载场景中会中断<代码>MyOwnClassName。班getResource从不中断,因此,请始终使用它)。

这要求java查找类文件所在的位置,而不是其他位置。您的类文件在jar文件中,而不是在它们旁边,因此,它找不到位于jar文件旁边的文本文件。

它在开发过程中工作是没有意义的:这意味着您将一个文件推到了resources文件夹中,这相当于在jar文件中有一个CSV文件。你一定是特意告诉你的构建系统去做一些奇怪的事情。不要那样做。

如果该CSV文件不打算被用户编辑,它应该在jar文件中而不是旁边:这使它成为应用程序资源。应用程序资源示例:

  • 你有一个GUI,你需要存储图标文件和闪屏艺术等等
  • 你的应用程序附带静态数据,比如美国各州的表格以及它们使用的Zipcode(例如可以是文本或csv文件)
  • 配置文件模板。不配置文件本身
  • 需要解包的DLL等(因为windows/linux/mac不会在JAR中查找它们)
  • 您是一个Web应用程序,希望将HTML静态文件与您的Web应用程序一起发布

如果CSV文件是这样的,那么修复方法是将它放在jar中,而不是放在它旁边,然后用MyClass加载它。班获取资源(名称)

例如:

  • 对于富文本编辑器(比如LibreOffice Writer),可以使用。odt表示您的作品的文件

这些不应该在jar中,根本不应该加载. getResources,并且首先不应该在src/main/Resources中。

它们也不应该在你的罐子旁边!这是一种过时且不安全的模式(即可编辑文件与应用程序位于同一位置的想法):适当的操作系统配置意味着应用程序无法写入自身,这最容易通过使其无法写入其目录来实现。一些操作系统(尤其是windows)曾经犯过这样的错误。

例如,在windows上,您的应用程序位于C:\Program Files\MakorisAwesomeApp\makori.jar中,它的数据文件位于C:\User\UserThatInstalldIt\Documents\MakorisAwesomeApp中的某个位置。

哦,linux,你的应用程序可能是usr/bin/makori,数据位于home目录的某个地方。配置数据可能存在于etc中。

您不“发布”您的配置文件,而是制作创建它们的安装程序。您可以在应用程序中完成这一部分,方法是检测到相关的配置文件不存在,加载模板(这是一个资源,在您的jar中提供,加载getResources),并将其写出来,并告诉用户去查看并编辑它。

嗯,这是错误的,所以,没有库可以让这变得容易。当你想做一些愚蠢的事情时,API并不能让这件事变得简单,这是好事,对吧?

有很多方法可以做到这一点。您可以使用。getResource获取URL,然后对其进行“解析”。这打破了类加载器的抽象概念(因为在java中,您可以编写自己的类加载器,它们可以从任何地方加载,而不仅仅是JAR中的文件或条目),但您可以询问“您自己”(MyClass.class.getResource(“MyClass.class”)),分离URL并找出发生了什么-它是从文件开始的吗?然后它是一个文件,所以把它转换成一个j.i.file对象,然后从那里开始。它是以jar开头的吗?找到<代码> ,子串出jar部分,现在您知道jar了。让它成为java。io。文件,请求父目录,并在那里查找CSV。

你必须把这些都写下来。这是一个很难测试的复杂代码。你不应该这样做。

 类似资料:
  • 我有一个名为的项目,它有以下结构: 所以这两个文件的路径是: 我想读测试文件。TestDataProvider中的json。JAVA 我曾经用过 我看到从URL res=getClass(). getClassLoader(). getResources("testfile.json")返回; 有人能帮我吗?

  • 我想从我的jar中读取一个资源,如下所示: 在Eclipse中运行它时工作良好,但如果我将它导出到一个jar中,然后运行它,就会出现一个IllegalArgumentException: 我真的不知道为什么,但通过一些测试我发现如果我改变 至 然后它的工作方式相反(它在jar中工作,但不能在eclipse中工作)。 我使用的是Eclipse,我的文件所在的文件夹位于类文件夹中。

  • 如何从资源文件夹的子文件夹中读取文件。 我在资源文件夹中有一些json文件,例如: 现在我想在我的课堂上读到这个 这是我正在尝试的,但是失败了。 不起作用,那么我正在尝试: 这两样东西都不工作。

  • 问题内容: 我正在使用Spring Boot和。我正在尝试从文件夹读取一个文件。我尝试了几种不同的方法,但无法正常工作。这是我的代码。 这是文件的位置。 在这里,我可以看到文件夹中的文件。 但是,当我运行代码时,出现以下错误。 我在代码中做错了什么? 问题答案: 在花费大量时间尝试解决此问题之后,终于找到了可行的解决方案。该解决方案利用了Spring的ResourceUtils。也应该适用于jso

  • 问题内容: 我正在尝试从作为桌面应用程序运行的单独jar中访问jar文件中的XML文件。我可以获取所需文件的URL,但是当我将其传递给FileReader(作为字符串)时,我得到了FileNotFoundException,上面写着“文件名,目录名或卷标语法不正确”。 作为参考,我毫不费力地从同一个jar中读取图像资源,并将URL传递给ImageIcon构造函数。这似乎表明我用来获取URL的方法是

  • 问题内容: 我开发了一个应用程序,可以从用户选择的文件夹中读取文件。它显示每个文件中有多少行代码。我只希望Java文件显示在文件选择器(扩展名为.java的文件)中。下面是我的代码: 我也进行了编辑,但是仍然无法正常工作,请告知请告知如何仅读取扩展名为.java的文件,换句话说,请仅从文件夹中读取java文件,请告知 问题答案: 您需要一个FilenameFilter。这应该为您工作: