如何获取Java JAR文件中资源的路径
我正试图找到一条通往资源的路径,但我没有运气 这可以(在IDE和JAR中)工作,但这样我无法获得文件的路径,只有文件内容:如何获取Java JAR文件中资源的路径,java,resources,path,Java,Resources,Path,我正试图找到一条通往资源的路径,但我没有运气 这可以(在IDE和JAR中)工作,但这样我无法获得文件的路径,只有文件内容: ClassLoader classLoader = getClass().getClassLoader(); PrintInputStream(classLoader.getResourceAsStream("config/netclient.p")); 如果我这样做: ClassLoader classLoader = getClass().getClassLoader
ClassLoader classLoader = getClass().getClassLoader();
PrintInputStream(classLoader.getResourceAsStream("config/netclient.p"));
如果我这样做:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("config/netclient.p").getFile());
结果是:
java.io.FileNotFoundException:file:/path/to/jarfile/bot.jar/config/netclient.p(没有这样的文件或目录)
有没有办法获得资源文件的路径?这是经过深思熟虑的。“文件”的内容可能无法作为文件使用。请记住,您正在处理的类和资源可能是JAR文件或其他类型资源的一部分。类加载器不必为资源提供文件句柄,例如,jar文件可能没有扩展到文件系统中的单个文件中
如果绝对需要java.io.File,那么获取java.io.File所能做的任何事情都可以通过将流复制到一个临时文件中并执行相同的操作来完成。如果
netclient.p
在JAR文件中,它将没有路径,因为该文件位于其他文件中。在这种情况下,最好的路径就是file:/path/to/jarfile/bot.jar/config/netclient.p
文件是文件系统中文件的抽象,文件系统对JAR的内容一无所知
尝试使用URI,我认为有一个jar://协议可能对您的purpouse有用。您需要了解jar文件中的路径。
简单地说它是相对的。因此,如果您有一个文件(myfile.txt),位于foo.jar的
\src\main\resources
目录下(maven样式)。您可以这样引用它:
src/main/resources/myfile.txt
如果您使用
jar-tvf myjar.jar
转储jar,您将看到jar文件中的输出和相对路径,并使用前斜杠。我花了一段时间来处理这个问题,因为我发现没有一个解决方案真正起作用,真是太奇怪了!工作目录通常不是JAR的目录,特别是当JAR(或任何程序)是从Windows下的“开始”菜单运行时。这就是我所做的,它适用于从JAR外部运行的.class文件,就像适用于JAR一样。(我只在Windows7下测试过。)
以下路径对我有效:
classpath:/path/to/resource/in/jar
加载资源时,请确保注意以下两者之间的区别:
getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
及
我想,在加载资源时,这种混乱会导致大多数问题
此外,在加载图像时,使用
getResourceAsStream()
更容易:
当您确实需要从JAR存档加载(非映像)文件时,您可以尝试以下方法:
File file = null;
String resource = "/com/myorg/foo.xml";
URL res = getClass().getResource(resource);
if (res.getProtocol().equals("jar")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.close();
file.deleteOnExit();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if (file != null && !file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}
在jar文件中,资源绝对位于包层次结构(而不是文件系统层次结构)中。因此,如果您让com.example.Sweet类加载名为“./default.conf”的资源,那么该资源的名称将被指定为“/com/example/default.conf” 但是如果它在一个罐子里,那么它就不是一个文件
private static final String FILE_LOCATION = "com/input/file/somefile.txt";
//Method Body
InputStream invalidCharacterInputStream = URLClassLoader.getSystemResourceAsStream(FILE_LOCATION);
从getSystemResourceAsStream获取此信息是最好的选择。通过获取inputstream而不是文件或URL,可以在JAR文件中独立工作。一行回答是-
String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
String path=this.getClass().getClassLoader().getResource().toExternalForm()
基本上,getResource
方法给出URL。
通过调用toExternalForm()
参考资料:
,,
这是来自用户Tombart的相同代码,具有流刷新和关闭功能,以避免从jar资源复制不完整的临时文件内容,并具有唯一的临时文件名
File file = null;
String resource = "/view/Trial_main.html" ;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile(new Date().getTime()+"", ".html");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
input.close();
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
在我的例子中,我使用了一个URL对象来代替路径 文件
File file = new File("my_path");
URL url = file.toURI().toURL();
使用类加载器在类路径中创建资源
URL url = MyClass.class.getClassLoader().getResource("resource_name")
当我需要阅读内容时,我可以使用以下代码:
InputStream stream = url.openStream();
您可以使用InputStream访问内容。在jar的resources文件夹(java/main/resources)中添加您的文件(我们假设您添加了一个名为imports.xml的xml文件),然后,如果您使用类似spring的bellow,您可以插入
ResourceLoader
@Autowired
private ResourceLoader resourceLoader;
内部巡更功能写入以下代码以加载文件:
Resource resource = resourceLoader.getResource("classpath:imports.xml");
try{
File file;
file = resource.getFile();//will load the file
...
}catch(IOException e){e.printStackTrace();}
可能有点晚,但您可以使用我的库从您的jar获取资源:
File resource = getResource("file.txt")
也许这种方法可以用于快速求解
public class TestUtility
{
public static File getInternalResource(String relativePath)
{
File resourceFile = null;
URL location = TestUtility.class.getProtectionDomain().getCodeSource().getLocation();
String codeLocation = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
resourceFile = path.toFile();
}else{
//Call from IDE
resourceFile = new File(TestUtility.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return resourceFile;
}
}
遵循代码
/src/main/resources/file
streamToFile(getClass().getClassLoader().getResourceAsStream(“文件”))
公共静态文件streamToFile(InputStream in){
if(in==null){
返回null;
}
试一试{
File f=File.createTempFile(String.valueOf(in.hashCode()),“.tmp”);
f、 deleteOnExit();
FileOutputStream out=新的FileOutputStream(f);
字节[]缓冲区=新字节[1024];
int字节读取;
while((bytesRead=in.read(buffer))!=-1){
out.write(缓冲区,0,字节读取);
}
返回f;
}捕获(IOE异常){
LOGGER.error(e.getMessage(),e);
返回null;
}
}
是。我有一个我想同时使用的类,一个在外部的文件夹(以防我想更改配置文件的一些参数)和一个向用户隐藏实现配置文件的JAR(就像一个可分发给所有人的JAR)。因此该类只接收到一个文件(配置文件)的路径。那么你可能应该让那个类处理输入流,你可以从任何一个来源获得。是的,我知道。但如果换成另一种方式,情况会更清楚、更干净。但无论如何,thx。在这个问题上,你是否在尝试做类似选项4的事情+这对我很有效。在使用“/com/myorg/filename.ext”路径之前,请确保将要读取的文件放置在bin
文件夹中,并转到资源中加载的类的目录。+1
Resource resource = resourceLoader.getResource("classpath:imports.xml");
try{
File file;
file = resource.getFile();//will load the file
...
}catch(IOException e){e.printStackTrace();}
File resource = getResource("file.txt")
public class TestUtility
{
public static File getInternalResource(String relativePath)
{
File resourceFile = null;
URL location = TestUtility.class.getProtectionDomain().getCodeSource().getLocation();
String codeLocation = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
resourceFile = path.toFile();
}else{
//Call from IDE
resourceFile = new File(TestUtility.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return resourceFile;
}
}