【问题标题】:Can I store a file in an ArrayList in Java using getResource?我可以使用 getResource 将文件存储在 Java 中的 ArrayList 中吗?
【发布时间】:2013-08-14 23:34:59
【问题描述】:

Java 新手。我正在构建一个 Java HTTP 服务器(不允许使用特殊库)。我需要提供某些文件(我称之为模板),我正在使用这段代码来提供它们:

this.getClass().getResourceAsStream("/http/templates/404.html")

并将它们包含在我的 .jar 中。这行得通。 (我意识到我正在将它们作为输入流读取。)

现在我想将模板、常规文件、重定向的所有文件(作为文件类型)存储在一个哈希图中,如下所示:url -> 文件。我有一个提供文件的 Response 类。

这适用于除我的模板之外的所有内容。如果我尝试在 hashmap 中插入 getResource 代码,我的 Response 类中会出现错误。

这是我用来构建哈希图的代码:

new File(this.getClass().getResource("/http/templates/404.html").getFile())

这是我得到的错误:

Exception in thread "main" java.io.FileNotFoundException: file:/Users/Kelly/Desktop/Java_HTTP_Server/build/jar/server.jar!/http/templates/404.html (No such file or directory)

我运行了这个命令,可以看到我的 jar 中的模板:

jar tf server.jar

我的想法哪里出错了?我想我漏掉了一块拼图。

更新:这是我运行上面最后一个命令时得到的一部分......所以我认为我有正确的文件路径?

http/server/serverSocket/SystemServerSocket.class
http/server/serverSocket/WebServerSocket.class
http/server/ServerTest.class
http/templates/
http/templates/404.html
http/templates/file_directory.html
http/templates/form.html

【问题讨论】:

  • 尝试使用 getPath() 而不是 getFile()。另外,请确保这是一个有效的路径。
  • 谢谢,乔希!虽然没有工作。我得到了同样的错误。此外,我更新了我的问题以显示我的 server.jar 中的内容。
  • 异常的消息文本应该给你一个线索:它是对 jar 文件的一些引用,它可能以Stream 打开,但不是正确的File 位置。为什么这里需要File 对象?
  • 感谢您的帮助,陀螺。哈希图中的所有其他值(对于每个键/值对)都是文件。因此,似乎需要对模板进行一些重新编码才能使模板不是文件而其余的都是文件?

标签: java http getresource


【解决方案1】:

您得到的FileNotFoundException 错误不是来自这一行:

new File(this.getClass().getResource("/http/templates/404.html").getFile())

似乎在您将这些 File 对象存储在哈希映射中之后,您正在尝试读取文件(或通过使用 FileInputStream 或相关 API 读取来提供文件)。如果您提供了堆栈跟踪和实际引发此异常的代码,那将会更有用。

但关键是 JAR 文件中存在的文件与磁盘上的文件不同。特别是,File 对象表示磁盘上的抽象路径名,所有使用File 对象的标准库都假定它是可访问的。所以/a/path/like/this 是一个有效的抽象路径名,但file:/Users/Kelly/Desktop/Java_HTTP_Server/build/jar/server.jar!/http/templates/404.html 不是。这正是您致电getResource("/http/templates/404.html").getFile() 时所得到的。它只是返回一个字符串,该字符串表示磁盘上不存在的文件。

有两种方法可以直接从类路径提供资源:

  • 直接返回流作为对请求的响应。 this.getClass().getResourceAsStream() 将返回 InputStream 对象,然后您可以将其返回给调用者。这将要求您将 InputStream 对象存储在哈希映射中而不是文件中。您可以有两个哈希映射,一个用于类路径中的文件,一个用于磁盘上的文件。
  • 将所有模板(可能在首次访问时)提取到一个临时位置,例如/tmp,然后存储代表新提取文件的File 对象。

【讨论】:

  • 抱歉耽搁了。你在这点上是完全正确的。为了解决这个问题,我简单地抓取了资源(使用输入流)并用它制作了一个临时文件。感谢您的帮助!
猜你喜欢
  • 2014-12-05
  • 2014-12-19
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
相关资源
最近更新 更多