为啥我的 URI 不是分层的? [复制]
Posted
技术标签:
【中文标题】为啥我的 URI 不是分层的? [复制]【英文标题】:Why is my URI not hierarchical? [duplicate]为什么我的 URI 不是分层的? [复制] 【发布时间】:2013-08-05 23:37:52 【问题描述】:我在资源文件夹中有文件。例如,如果我需要从资源文件夹中获取文件,我会这样做:
File myFile= new File(MyClass.class.getResource(/myFile.jpg).toURI());
System.out.println(MyClass.class.getResource(/myFile.jpg).getPath());
我已经测试过并且一切都有效!
路径是
/D:/java/projects/.../classes/X/Y/Z/myFile.jpg
但是,如果我创建 jar 文件,使用 Maven:
mvn package
...然后启动我的应用程序:
java -jar MyJar.jar
我有以下错误:
Exception in thread "Thread-4" java.lang.RuntimeException: ხელმოწერის განხორციელება შეუძლებელია
Caused by: java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:363)
...文件的路径是:
file:/D:/java/projects/.../target/MyJar.jar!/X/Y/Z/myFile.jpg
当我尝试从资源文件夹中获取文件时会发生此异常。在这一行。为什么?为什么在 JAR 文件中有这个问题?你怎么看?
还有其他方法,获取资源文件夹路径吗?
【问题讨论】:
你可以看看这个:***.com/questions/10144210/… 和接受的答案。 【参考方案1】:你应该使用
getResourceAsStream(...);
当资源被捆绑为 jar/war 或任何其他单个文件包时。
看问题是,一个 jar 是一个包含许多文件的单个文件(有点像 zip 文件)。从 Os 的 pov 来看,它是一个文件,如果您想访问 part of the file
(您的图像文件),您必须将其用作流。
Documentation
【讨论】:
是否有可能将其转换为 java.io.File? 好吧,我从 docker 容器中得到了同样的错误,但只有当它在 k8s 集群中运行时。在 IDE 或 docker 容器中运行时,我没有错误。如果这有帮助... 如果我想列出目录中的文件,使用它们的文件名,并将每个文件的文本单独读入 java 对象,该怎么办? 我用这个转换成一个文件:FileUtils.copyInputStreamToFile(inputStream, file);【参考方案2】:这是 Eclipse RCP / 插件开发人员的解决方案:
Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try
URL resolvedFileURL = FileLocator.toFileURL(fileURL);
// We need to use the 3-arg constructor of URI in order to properly escape file system chars
URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
File file = new File(resolvedURI);
catch (URISyntaxException e1)
e1.printStackTrace();
catch (IOException e1)
e1.printStackTrace();
使用FileLocator.toFileURL(fileURL)
而不是resolve(fileURL)
非常重要
, 因为当插件被打包到一个 jar 中时,这将导致 Eclipse 在一个临时位置创建一个解压版本,以便可以使用 File 访问该对象。例如,我猜 Lars Vogel 在他的文章中有一个错误 - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/
【讨论】:
谢谢你,我欠你一杯啤酒,确实 Vogella 的文章需要更新。 help.eclipse.org/indigo/… 这个解决方案似乎依赖于平台。有没有办法从 IntelliJ 实现类似的东西而不必导入 "org.eclipse.core.runtime.FileLocator" ? @Kwoinkwoin,是的,这个解决方案适用于 eclipse rcp 插件开发人员。我建议尝试 getResourceAsStream(...) 方法 此解决方案与平台无关【参考方案3】:我在公司从事一个项目时遇到了同样的问题。首先,URI 不是分层的问题是因为您可能使用“/”作为文件分隔符。
您必须记住,“/”是针对 Windows 的,并且从操作系统到操作系统它会发生变化,在 Linux 中可能会有所不同。因此使用 File.seperator 。
所以使用
this.getClass().getClassLoader().getResource("res"+File.separator+"secondFolder")
可能会删除不分层的 URI。但是现在您可能会遇到空指针异常。我尝试了很多不同的方法,然后使用 JarEntries 类来解决它。
File jarFile = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
String actualFile = jarFile.getParentFile().getAbsolutePath()+File.separator+"Name_Of_Jar_File.jar";
System.out.println("jarFile is : "+jarFile.getAbsolutePath());
System.out.println("actulaFilePath is : "+actualFile);
final JarFile jar = new JarFile(actualFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
System.out.println("Reading entries in jar file ");
while(entries.hasMoreElements())
JarEntry jarEntry = entries.nextElement();
final String name = jarEntry.getName();
if (name.startsWith("Might Specify a folder name you are searching for")) //filter according to the path
System.out.println("file name is "+name);
System.out.println("is directory : "+jarEntry.isDirectory());
File scriptsFile = new File(name);
System.out.println("file names are : "+scriptsFile.getAbsolutePath());
jar.close();
您必须在此处明确指定 jar 名称。所以使用这段代码,这将为您提供 jar 文件夹内的目录和子目录。
【讨论】:
如果您将包装从 jar 更改为另一个压缩文件实现(如 zip)怎么办?这行得通吗?如果您正在构建一个库而用户不会使用 jar 打包怎么办?以上是关于为啥我的 URI 不是分层的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章