打开存储在资源文件夹中的PDF文件会引发异常

时间:2019-07-05 11:15:08

标签: java file resources

我编写了一个程序,其中应在动作事件中打开pdf文件(您可以在下面查看我的代码)。

menuElementHilfe.addActionListener(new ActionListener() {   
    public void actionPerformed(ActionEvent arg0) {
        File hilfe = new File ("src\\resources\\Hilfe.pdf");
        try {
            java.awt.Desktop.getDesktop().open(hilfe);
        } catch (IOException e) {
            e.printStackTrace();
        }       
    }   
});

如果我通过Eclipse执行程序,则一切正常,但是导出为可运行的jar后,出现以下异常:

  

线程“ AWT-EventQueue-0”中的异常java.lang.IllegalArgumentException:文件src \ resources \ Hilfe.pdf不存在。

感谢任何反馈

2 个答案:

答案 0 :(得分:0)

您检索资源的方式可能是问题所在。试试这个:

menuElementHilfe.addActionListener(new ActionListener() {   
    public void actionPerformed(ActionEvent arg0) {
    File hilfe = new File(getClass().getResource("/resources/Hilfe.pdf").getFile());
        try {
        java.awt.Desktop.getDesktop().open(hilfe);
        } catch (IOException e) {
            e.printStackTrace();
        }       
    }   
});

在Eclipse中运行时,您将目标定位为构建路径中的文件。 从JAR / WAR运行时,URL不同,看起来像“ jar:file:/your-path/your-jar.jar!/Hilfe.pdf” ,这不是您在调用时设置的new File(...)因此,要获取内部资源的正确URL,必须根据需要使用诸如getResource或getResourceAsStream之类的方法。

查看以下说明以获取更多信息:) https://docs.oracle.com/javase/8/docs/technotes/guides/lang/resources.html

[编辑]

我假设您正在使用某些Swing应用程序,但是我不知道您是否知道在AWT-EventQueue线程中执行类似的任务会冻结UI。 为了防止这种情况,您必须在另一个线程中运行与UI无关的内容。

  

这是使用SwingUtilities.invokeLater(Java 5和更低版本)方法和/或SwingWorker类(自Java 6开始)实现的。

如本answer

所述

您应该将先前的解决方案放入类似的内容中:

 SwingUtilities.invokeLater(new Runnable() {
    public void run() {
       // Your UI unrelated code here
    }
 });

答案 1 :(得分:0)

资源可以打包在应用程序jar中,因此可以打包为File(物理磁盘文件) 不可能。将其复制到一个临时文件中,以便桌面可以打开它。

menuElementHilfe.addActionListener(evt -> {   
    Path tmp = Files.createTempFile("hilfe-", ".pdf");
    Files.copy(getClass().getResourceAsStream("/Hilfe.pdf"), tmp);
    try {
        Desktop.getDesktop().open(tmp.toFile());
        tmp.toFile().deleteOnExit();
    } catch (IOException e) {
        e.printStackTrace();
    }       
});

另一个区别是正斜杠,并且路径与Windows File相对,区分大小写。


出现问题后

menuElementHilfe.addActionListener(evt ->
        SwingUtilities.invokeLater(() -> {
            Path tmp = Files.createTempFile("hilfe-", ".pdf");
            Logger.getLogger(getClass().getName()).log(Level.INFO, "actionPerformed "
                    + tmp + "; event: " + evt);
            Files.copy(getClass().getResourceAsStream("/resources/Hilfe.pdf"), tmp);
            try {
                Desktop.getDesktop().open(tmp.toFile());
                //tmp.toFile().deleteOnExit();
            } catch (IOException e) {
                Logger.getLogger(getClass().getName()).log(Level.WARN, "Error with " + tmp,
                        e);
            }       
        }));
  • 我没有删除,因此Desktop访问的寿命比Java应用程序长。
  • 我做了一个invokeLater是为了使actionPerformed上没有冻结的GUI。
  • 我添加了日志记录以查看对actionPerformed的每次调用