Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何列出JAR文件中的文件?_Java_File_Jar_Java Io_Getresource - Fatal编程技术网

Java 如何列出JAR文件中的文件?

Java 如何列出JAR文件中的文件?,java,file,jar,java-io,getresource,Java,File,Jar,Java Io,Getresource,我有一个从目录中读取所有文件的代码 File textFolder = new File("text_directory"); File [] texFiles = textFolder.listFiles( new FileFilter() { public boolean accept( File file ) { return file.getName().endsWith(".txt"); }

我有一个从目录中读取所有文件的代码

    File textFolder = new File("text_directory");

    File [] texFiles = textFolder.listFiles( new FileFilter() {
           public boolean accept( File file ) {
               return file.getName().endsWith(".txt");
           }
    });
它工作得很好。它用目录“text\u directory”中以“.txt”结尾的所有文件填充数组

如何在JAR文件中以类似的方式读取目录的内容

所以我真正想做的是,列出我JAR文件中的所有图像,这样我就可以加载它们了:

ImageIO.read(this.getClass().getResource("CompanyLogo.png"));
(这是因为“CompanyLogo”是“硬编码”的,但是JAR文件中的图像数量可以是10到200个可变长度。)

编辑

所以我想我的主要问题是:如何知道我的主类所在的JAR文件名

当然,我可以使用
java.util.Zip
阅读它

我的结构是这样的:

它们是:

my.jar!/Main.class
my.jar!/Aux.class
my.jar!/Other.class
my.jar!/images/image01.png
my.jar!/images/image02a.png
my.jar!/images/imwge034.png
my.jar!/images/imagAe01q.png
my.jar!/META-INF/manifest 
现在,我可以使用以下方法加载例如“images/image01.png”:


但这只是因为我知道文件名,其余的我必须动态加载它们。

jar文件只是一个带有结构化清单的zip文件。您可以使用常用的JavaZIP工具打开jar文件,并以这种方式扫描文件内容,膨胀流,等等。然后在getResourceAsStream调用中使用它,它应该是完美的

编辑/澄清后

我花了一分钟的时间记住了所有的细节,我确信有更干净的方法来做到这一点,但我想知道我没有疯。在我的项目中,image.jpg是主jar文件的某个部分中的一个文件。我得到了主类的类加载器(SomeClass是入口点),并使用它来发现image.jpg资源。然后用一些流魔法把它放到ImageInputStream中,一切都很好

InputStream inputStream = SomeClass.class.getClassLoader().getResourceAsStream("image.jpg");
JPEGImageReaderSpi imageReaderSpi = new JPEGImageReaderSpi();
ImageReader ir = imageReaderSpi.createReaderInstance();
ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
ir.setInput(iis);
....
ir.read(0); //will hand us a buffered image

给定一个实际的JAR文件,您可以使用
JarFile.entries()
列出内容。不过,您需要知道JAR文件的位置——您不能只要求类加载器列出它可以得到的所有内容


您应该能够根据从
ThisClassName.class.getResource(“ThisClassName.class”)
返回的URL计算出JAR文件的位置,但这可能有点麻烦。

我为“在一个包下运行所有JUnits”编写了一个方法。你应该能够使它适应你的需要

private static void findClassesInJar(List<String> classFiles, String path) throws IOException {
    final String[] parts = path.split("\\Q.jar\\\\E");
    if (parts.length == 2) {
        String jarFilename = parts[0] + ".jar";
        String relativePath = parts[1].replace(File.separatorChar, '/');
        JarFile jarFile = new JarFile(jarFilename);
        final Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            final JarEntry entry = entries.nextElement();
            final String entryName = entry.getName();
            if (entryName.startsWith(relativePath)) {
                classFiles.add(entryName.replace('/', File.separatorChar));
            }
        }
    }
}
private static void findClassesInJar(列出类文件,字符串路径)抛出IOException{
最终字符串[]部分=path.split(\\Q.jar\\\\E”);
如果(parts.length==2){
字符串jarFilename=parts[0]+“.jar”;
字符串relativePath=parts[1]。替换(File.separatorChar,“/”);
JarFile JarFile=新的JarFile(jarFilename);
最终枚举条目=jarFile.entries();
while(entries.hasMoreElements()){
final JarEntry=entries.nextElement();
最后一个字符串entryName=entry.getName();
if(entryName.startsWith(relativePath)){
add(entryName.replace('/',File.separatorChar));
}
}
}
}
编辑: 啊,在这种情况下,您可能也需要这个代码段(相同的用例:)

私有静态文件findClassesDir(类clazz){
试一试{
字符串路径=clazz.getProtectionDomain().getCodeSource().getLocation().getFile();
最终字符串codeSourcePath=URLDecover.decode(路径“UTF-8”);
最后一个字符串thisClassPath=新文件(codeSourcePath,clazz.getPackage().getName().repalce('.',File.separatorChar));
}捕获(不支持的编码异常e){
抛出新断言错误(“不可能”,e);
}
}
注意,在Java7中,您可以从JAR(zip)文件创建一个
文件系统
,然后使用NIO的目录遍历和过滤机制进行搜索。这将使编写处理JAR和“分解”目录的代码变得更容易

所以我想我的主要问题是,如何知道我的主类所在的jar的名称

假设您的项目打包在一个Jar中(不一定是真的!),您可以使用ClassLoader.getResource()或findResource()和类名(后跟.class)来获取包含给定类的Jar。您必须从返回的URL解析jar名称(不是那么难),我将留给读者作为练习:-)

确保测试类不是jar的一部分的情况。

erickson的工作非常好:

这是工作代码

CodeSource src = MyClass.class.getProtectionDomain().getCodeSource();
List<String> list = new ArrayList<String>();

if( src != null ) {
    URL jar = src.getLocation();
    ZipInputStream zip = new ZipInputStream( jar.openStream());
    ZipEntry ze = null;

    while( ( ze = zip.getNextEntry() ) != null ) {
        String entryName = ze.getName();
        if( entryName.startsWith("images") &&  entryName.endsWith(".png") ) {
            list.add( entryName  );
        }
    }

 }
 webimages = list.toArray( new String[ list.size() ] );
为此:

String  [] webimages = ...

BufferedImage image = ImageIO.read(this.getClass().getResource(webimages[nextIndex]));

有两个非常有用的实用程序,都称为JarScan:


  • 另请参见此问题:

    不久前,我制作了一个从JAR内部获取classess的函数:

    public static Class[] getClasses(String packageName) 
    throws ClassNotFoundException{
        ArrayList<Class> classes = new ArrayList<Class> ();
    
        packageName = packageName.replaceAll("\\." , "/");
        File f = new File(jarName);
        if(f.exists()){
            try{
                JarInputStream jarFile = new JarInputStream(
                        new FileInputStream (jarName));
                JarEntry jarEntry;
    
                while(true) {
                    jarEntry=jarFile.getNextJarEntry ();
                    if(jarEntry == null){
                        break;
                    }
                    if((jarEntry.getName ().startsWith (packageName)) &&
                            (jarEntry.getName ().endsWith (".class")) ) {
                        classes.add(Class.forName(jarEntry.getName().
                                replaceAll("/", "\\.").
                                substring(0, jarEntry.getName().length() - 6)));
                    }
                }
            }
            catch( Exception e){
                e.printStackTrace ();
            }
            Class[] classesA = new Class[classes.size()];
            classes.toArray(classesA);
            return classesA;
        }else
            return null;
    }
    
    publicstaticclass[]getClasses(stringpackagename)
    抛出ClassNotFoundException{
    ArrayList类=新的ArrayList();
    packageName=packageName.replaceAll(“\\”,“/”);
    文件f=新文件(jarName);
    如果(f.exists()){
    试一试{
    JarInputStream jarFile=新的JarInputStream(
    新文件输入流(jarName));
    JarEntry-JarEntry;
    while(true){
    jarEntry=jarFile.getNextJarEntry();
    if(jarEntry==null){
    打破
    }
    if((jarEntry.getName().startsWith(packageName))&&
    (jarEntry.getName().endsWith(“.class”)){
    Class.add(Class.forName(jarEntry.getName())。
    全部替换(“/”,“\\”)。
    子字符串(0,jarEntry.getName().length()-6));
    }
    }
    }
    捕获(例外e){
    e、 printStackTrace();
    }
    Class[]classesA=新类[classes.size()];
    类。toArray(类ESA);
    返回类a;
    }否则
    返回null;
    }
    
    同时适用于IDE和.jar文件的代码:

    import java.io.*;
    import java.net.*;
    import java.nio.file.*;
    import java.util.*;
    import java.util.stream.*;
    
    public class ResourceWalker {
        public static void main(String[] args) throws URISyntaxException, IOException {
            URI uri = ResourceWalker.class.getResource("/resources").toURI();
            Path myPath;
            if (uri.getScheme().equals("jar")) {
                FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.<String, Object>emptyMap());
                myPath = fileSystem.getPath("/resources");
            } else {
                myPath = Paths.get(uri);
            }
            Stream<Path> walk = Files.walk(myPath, 1);
            for (Iterator<Path> it = walk.iterator(); it.hasNext();){
                System.out.println(it.next());
            }
        }
    }
    
    import java.io.*;
    导入java.net。*;
    导入java.nio.file.*;
    导入java.util.*;
    导入java.util
    
    File[] webimages = ... 
    BufferedImage image = ImageIO.read(this.getClass().getResource(webimages[nextIndex].getName() ));
    
    String  [] webimages = ...
    
    BufferedImage image = ImageIO.read(this.getClass().getResource(webimages[nextIndex]));
    
    public static Class[] getClasses(String packageName) 
    throws ClassNotFoundException{
        ArrayList<Class> classes = new ArrayList<Class> ();
    
        packageName = packageName.replaceAll("\\." , "/");
        File f = new File(jarName);
        if(f.exists()){
            try{
                JarInputStream jarFile = new JarInputStream(
                        new FileInputStream (jarName));
                JarEntry jarEntry;
    
                while(true) {
                    jarEntry=jarFile.getNextJarEntry ();
                    if(jarEntry == null){
                        break;
                    }
                    if((jarEntry.getName ().startsWith (packageName)) &&
                            (jarEntry.getName ().endsWith (".class")) ) {
                        classes.add(Class.forName(jarEntry.getName().
                                replaceAll("/", "\\.").
                                substring(0, jarEntry.getName().length() - 6)));
                    }
                }
            }
            catch( Exception e){
                e.printStackTrace ();
            }
            Class[] classesA = new Class[classes.size()];
            classes.toArray(classesA);
            return classesA;
        }else
            return null;
    }
    
    import java.io.*;
    import java.net.*;
    import java.nio.file.*;
    import java.util.*;
    import java.util.stream.*;
    
    public class ResourceWalker {
        public static void main(String[] args) throws URISyntaxException, IOException {
            URI uri = ResourceWalker.class.getResource("/resources").toURI();
            Path myPath;
            if (uri.getScheme().equals("jar")) {
                FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.<String, Object>emptyMap());
                myPath = fileSystem.getPath("/resources");
            } else {
                myPath = Paths.get(uri);
            }
            Stream<Path> walk = Files.walk(myPath, 1);
            for (Iterator<Path> it = walk.iterator(); it.hasNext();){
                System.out.println(it.next());
            }
        }
    }
    
    URL urlResource = Thead.currentThread().getContextClassLoader().getResource("foo");
    JarReader.read(urlResource, new InputStreamCallback() {
        @Override
        public void onFile(String name, InputStream is) throws IOException {
            // got file name and content stream 
        }
    });
    
    Reflections reflections = new Reflections("com.example.package", new ResourcesScanner());
    Set<String> paths = reflections.getResources(Pattern.compile(".*\\.template$"));
    
    Map<String, String> templates = new LinkedHashMap<>();
    for (String path : paths) {
        log.info("Found " + path);
        String templateName = Files.getNameWithoutExtension(path);
        URL resource = getClass().getClassLoader().getResource(path);
        String text = Resources.toString(resource, StandardCharsets.UTF_8);
        templates.put(templateName, text);
    }
    
    import java.io.IOException;
    import java.net.*;
    import java.nio.file.*;
    import java.nio.file.attribute.BasicFileAttributes;
    import java.util.Collections;
    
    public class ResourceWalker {
    
        public static void main(String[] args) throws URISyntaxException, IOException {
            URI uri = ResourceWalker.class.getResource("/resources").toURI();
            System.out.println("Starting from: " + uri);
            try (FileSystem fileSystem = (uri.getScheme().equals("jar") ? FileSystems.newFileSystem(uri, Collections.<String, Object>emptyMap()) : null)) {
                Path myPath = Paths.get(uri);
                Files.walkFileTree(myPath, new SimpleFileVisitor<Path>() { 
                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                        System.out.println(file);
                        return FileVisitResult.CONTINUE;
                    }
                });
            }
        }
    }
    
    public static ArrayList<String> listItems(String path) throws Exception{
        InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(path);
        byte[] b = new byte[in.available()];
        in.read(b);
        String data = new String(b);
        String[] s = data.split("\n");
        List<String> a = Arrays.asList(s);
        ArrayList<String> m = new ArrayList<>(a);
        return m;
    }
    
    URI mainClasspathElementURI;
    try (ScanResult scanResult = new ClassGraph().whitelistPackages("x.y.z")
            .enableClassInfo().scan()) {
        mainClasspathElementURI =
                scanResult.getClassInfo("x.y.z.MainClass").getClasspathElementURI();
    }
    
    List<String> classpathElementResourcePaths;
    try (ScanResult scanResult = new ClassGraph().overrideClasspath(mainClasspathElementURI)
            .scan()) {
        classpathElementResourcePaths = scanResult.getAllResources().getPaths();
    }