【问题标题】:listing contents of a jar file [duplicate]列出 jar 文件的内容 [重复]
【发布时间】:2014-06-28 17:26:47
【问题描述】:

打包soundcliptest;

// development environment(NetBeans 8.0)
//
// NetBeansProjects
//     SoundClipTest
//         Source Packages
//             resources
//                ding.wav
//             soundcliptest
//                SoundClipTest.java
//

// unZipped jar file
//
// SoundClipTest
//    META-INF
//    resourses
//        ding.wav
//    soudcliptest
//        SoundClipTest.class
//

伙计们,我还在学习如何使用这个工具。我似乎无法获得它们所属的进口。

我需要知道如何从代码中查看 jar 文件。 File 方法无法破解它。必须有某种方法可以找到资源“目录”的内容。我想要做的是在 /resources/ 下制作声音文件的菜单。我可以使它在开发环境中工作,但不能从 jar 文件中工作。也许一些'zip'方法?但我还没有找到它们。提前致谢。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;

public class SoundClipTest extends JFrame {

    JTextPane myPane;
    String title;
    String showIt;

    public SoundClipTest() {

        // get something to write on
        this.myPane = new JTextPane();
        this.myPane.setPreferredSize(new Dimension(700, 100));
        this.myPane.setBorder(new BevelBorder(BevelBorder.LOWERED));

        try {
            // Open an audio input stream.
            URL dingUrl = getClass().getResource("/resources/ding.wav");

            // show the path we got
            String path = dingUrl.getPath();

            //trim 'ding.wav' from file path to get a directory path
            String dirPath = path.substring(0, path.length()-"ding.wav".length());

            // now get a Url for the dir from getResource and show THAT path
            URL dirUrl = getClass().getResource("/resources/");
            String urlPath = dirUrl.getPath();

            // the dirUrl path is just like the trimmed 'ding' file path
            // so use  urlPath to get a file object for the directory
            try {
                File f = new File(urlPath);  //works fine in dev environment
                String filePath = f.getPath();  // but not from jar file
                title = f.list()[0]; // from jar, null pointer exception here

                // whan things go right (HA HA) we display this
                showIt = ("                >>>>> IT WORKED!! <<<<<!" 
                        + "\n path to file:        "+ path 
                        + "\n path to dir:        " + dirPath 
                        + "\n path from URL: " +  urlPath  
                        + "\n path from file:  "+ filePath + "\n " + title);

            } catch (Exception e) {
                // you get this on display when executing the jar file
                showIt = ("          PHOOEY"
                        + "\n the ding  " + path 
                        + "\n trimmed path " + dirPath 
                        + "\n the URL path " + urlPath 
                        + "\n could not create a File object from path");

                 // the stack trace shows up only if you run from the terminal
               e.printStackTrace();
            }

            // We get a nice little 'ding', anyway
            AudioInputStream ais = AudioSystem.getAudioInputStream(dingUrl);
            Clip clip = AudioSystem.getClip();
            clip.open(ais);
            clip.start();

            //but nuttin else good -  show the disapointing results
            myPane.setText(showIt);

        } catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            System.out.println("Ouch!!! Damn, that hurt!");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SoundClipTest me = new SoundClipTest();
        JFrame frame = new JFrame("Sound Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(me.myPane, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}

【问题讨论】:

  • 嗯...有没有什么地方可以找到关于如何使用这个工具的解释?还是我只是继续试验。如果必须的话,我想我可以自己解决。

标签: java jar


【解决方案1】:

告售者

这是假设您没有使用类加载器,这将适用于 URLClassLoader,但它是该类的实现细节,而不是公共 API 的一部分。

如果您加载一个类路径目录资源,那么您将在该目录中为每个资源获取一行。

假设你有这个结构:

/resources
    /test1.txt
    /test2.txt

如果我们执行以下操作:

try (final Scanner scanner = new Scanner(getClass().getResourceAsStream("/resources"))) {
    while (scanner.hasNextLine()) {
        final String line = scanner.nextLine();
        System.out.println(line);
    }
}

这将输出:

test1.txt
test2.txt

因此您可以使用它来返回文件名列表:

List<String> readClassPath(final String root) {
    final List<String> resources = new LinkedList<>();
    try (final Scanner scanner = new Scanner(getClass().getResourceAsStream(root))) {
        while (scanner.hasNextLine()) {
            final String line = scanner.nextLine();
            System.out.println(line);
            resources.add(root + "/" + line);
        }
    }
    return resources;
}

这会返回:

[/resources/test1.txt, /resources/test2.txt]

【讨论】:

    【解决方案2】:

    好的,这不是一个完整的答案,但由于该部分没有很好的文档记录(Oracle 的页面已过时),以下是如何在 jar 文件上使用 ZIP 文件系统:

    final Path pathToJar = Paths.get(...).toRealPath();
    final String jarURL = "jar:file:" + pathToJar;
    final Map<String, String> env = new HashMap<>();
    
    final FileSystem jarfs = FileSystems.newFileSystem(URI.create(jarURL), env);
    
    final Path rootPath = jarfs.getPath("/resources");
    

    然后您可以使用Files.newDirectoryStream() 而不是rootPath 来获取jar 中“目录”内的文件列表。如果要递归列出,请使用Files.walkFileTree() 并编写自己的FileVisitor(大多数情况下,扩展SimpleFileVisitor 就足够了)。

    注意FileSystem 实现 Closeable;一旦你完成它,你应该确保.close()它。 DirectoryStream 也是如此。

    【讨论】:

      猜你喜欢
      • 2011-12-07
      • 1970-01-01
      • 2019-04-21
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多