Java 在运行时访问jar中的库资源

Java 在运行时访问jar中的库资源,java,file,jar,Java,File,Jar,我想使一个目录及其所有文件对一个方法可用。目录和文件位于 src/main/resources/images 并在运行时位于库jar中。我正在读目录 File directory = new File(getClass().getResource("/images").getFile()); 使用检查目录的内容 log.info("directory=" + directory.toString()); log.info("directory.isDirectory()=" + directo

我想使一个目录及其所有文件对一个方法可用。目录和文件位于

src/main/resources/images

并在运行时位于库jar中。我正在读目录

File directory = new File(getClass().getResource("/images").getFile());
使用检查
目录的内容

log.info("directory=" + directory.toString());
log.info("directory.isDirectory()=" + directory.isDirectory());
log.info("directory.isFile()=" + directory.isFile());
log.info("directory.canRead()=" + directory.canRead());
给予

  • directory=file:/home/leevillux/.m2/repository/groupid/library/1.0-SNAPSHOT/library-1.0-SNAPSHOT.jar/图像
  • directory.isDirectory()=false
  • directory.isFile()=false
  • directory.canRead()=false
很明显,它不是一个目录,不是一个文件,我无法阅读。但是
getFile
确实找到了一些东西,因为如果我使用
getResource(“/blabla”)
(它不存在),那么就会抛出一个空指针期望值(
java.lang.NullPointerException


我必须提取jar来创建“正常”路径吗?如果是,怎么做

是的,您必须提取您想要使用的资源。这不是别的办法。当您知道要使用的确切文件时,这很简单。您只需保存它,然后就可以使用它了

final InputStream directory = Main.class.getResourceAsStream("/images/name.jpg");
final byte[] buffer = new byte[directory.available()];
directory.read(buffer);
final File targetFile = new File("/tmp/target/name.jpg");
final OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
当您想要以目录为目标时,这并不容易。您必须检查jar的所有条目,并保存所有要使用的条目。然后,与上述情况一样,可以使用它们。类似于下面的示例

public class UnzipJar {
    public static void main(String[] args) throws IOException {
        final URL dirURL = UnzipJar.class.getResource("/images");
        final String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));

        extract("images", "/tmp/dest", jarPath);
    }

    public static void extract(final String source, final String destination, String jarPath) throws IOException {
        final File file = new File(jarPath);
        final JarFile jar = new JarFile(file);
        for (final Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
            final JarEntry entry = enums.nextElement();
            final String fileName = destination + File.separator + entry.getName();
            final File f = new File(fileName);
            if (fileName.startsWith(source) && !fileName.endsWith("/")) {
                final InputStream is = jar.getInputStream(entry);
                final FileOutputStream fos = new FileOutputStream(f);
                while (is.available() > 0) {
                    fos.write(is.read());
                }
                fos.close();
                is.close();
            }
        }
    }
}
public类UnzipJar{
公共静态void main(字符串[]args)引发IOException{
最终URL dirURL=UnzipJar.class.getResource(“/images”);
最后一个字符串jarPath=dirURL.getPath().substring(5,dirURL.getPath().indexOf(“!”);
提取(“图像”,“/tmp/dest”,jarPath);
}
公共静态void提取(最终字符串源、最终字符串目标、字符串路径)引发IOException{
最终文件=新文件(jarPath);
final JarFile jar=新JarFile(文件);
对于(最终枚举enums=jar.entries();enums.hasMoreElements();){
final JarEntry=enums.nextElement();
最终字符串文件名=destination+File.separator+entry.getName();
最终文件f=新文件(文件名);
if(fileName.startsWith(source)和&!fileName.endsWith(“/”){
最终的InputStream=jar.getInputStream(条目);
最终FileOutputStream fos=新FileOutputStream(f);
while(is.available()>0){
fos.write(is.read());
}
fos.close();
is.close();
}
}
}
}

删除前导斜杠->
“图像”
时会发生什么?资源不是文件。您可以提供另一个资源,列出所有图像的路径。读取路径列表,然后为每个列出的资源调用
getResource
。@Linonullpointerexception@Slaw我正在呼叫
getFile
相关: