java - 为什么我可以从 getClass().getResource() 获取有效的 url,但是返回的 url 会创建一个不存在的文件
问题描述
我正在尝试将一些数据加载到 AWS lambda 中,并使用 getClass().getResource() 来执行此操作。这会返回一个不错的 URL,在日志中似乎打印出一个合理的 url;但是,当我尝试根据该路径创建文件时,我得到一个文件,当我调用 .exists() 时返回 false。
如果我运行下面的代码,第一个打印语句给出“returns exists: false”
同时,第二个打印语句围绕“测试路径:/file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
File test = new File(cFile);
System.out.println("exists: " + test.exists());
System.out.println("test path: " + test.getAbsolutePath());
不知道为什么会这样。如果Java找到一个文件,那么我会假设该文件存在......
解决方案
简短的回答:不要假设 URL 的“路径”是文件系统路径名。
我正在尝试将一些数据加载到 AWS lambda 中,并使用 getClass().getResource() 来执行此操作。这会返回一个不错的 URL,在日志中似乎打印出一个合理的 url;
是的。(如果您向我们展示原始 URL 的样子,那就太好了……尽管我可以猜到。)
但是,当我尝试根据该路径创建文件时,我会得到一个文件,当我调用 .exists() 时会返回 false。
好的,除非 URL 具有协议“文件:”,否则我不希望它起作用。
URL 中的路径是供协议处理程序解析的路径。这个想法是您使用URL::openStream
打开一个流到由 URL 命名的资源然后读取它。协议处理程序负责解释路径(等)并设置流。
对于“file:” URL,协议处理程序将解析文件系统中的路径,并为您提供读取文件的流。
对于“http:” URL,协议处理程序建立与服务器的连接,发送 GET 请求,并返回一个流以读取响应正文。
对于“jar:”URL,协议处理程序会打开 JAR 文件,在 JAR 文件中找到条目,然后交给您一个流来读取它。
等等。
如果您查看这些,只有在“文件:”的情况下,才有合理的期望将 URL 的路径组件视为文件系统路径名可以工作。
查看问题中的路径名:
file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
我猜原来的网址是:
jar:file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
所以这对“jar:”协议处理程序说的是:
- 查找由 URL “file:/var/task/lib/MyLambda-1.0.jar”标识的资源
- 将其作为 JAR 文件流打开
- 在 JAR 文件的命名空间中找到条目“/com/my/package/folders/file.end”
- 打开一个流以读取该条目的内容。
JAR 文件协议处理程序知道如何做到这一点。但是(显然)File
该类没有......因为该“路径”不是文件系统路径名。
你如何解决这个问题取决于你真正需要什么。
- 如果您只需要一个流来读取资源,请
getClass().getResourceAsStream(...)
改用。 - 如果它必须是文件系统中的一个文件,您可能必须获取流(见上文),将其复制到一个临时文件,并使用 a
File
作为临时文件。
如果您这样做是因为您想写入“文件”,我建议您放弃这个想法。应用程序尝试更新其资源是一个坏主意。在某些情况下,它根本不会/无法工作。
推荐阅读
- java - java.lang.AbstractMethodError:尝试使用 Spring Boot 执行测试时出现配置错误
- sql - 如果在 Oracle SQL 中进行累积计数
- c++ - 无法在 Eclipse CDT C++ 中构建 OpenCV 项目
- python - 在 PySpark DataFrame 中添加多个空列
- python - TensorFlow 对象不显示
- ios - 当在 Swift 中的表中发生变化时更改表的标题
- android - 任务':app:transformDexArchiveWithExternalLibsDexMergerForDebug'的Android Studio执行失败
- bash - 在 bash shell 中查找所有匹配的文件并重命名
- python - 我试图通过传递字符串来获得最大数量
- hyperledger-fabric - 无法获取 chConfig 缓存引用:QueryBlockConfig 失败:queryChaincode 失败: