【问题标题】:pdf file does not open from the jar ubuntu 16.04pdf文件无法从jar ubuntu 16.04打开
【发布时间】:2018-05-05 21:19:22
【问题描述】:

我正在使用以下代码从 java 打开一个 pdf 文件。当我从 IDE 运行应用程序时,该代码有效。但是,当生成 jar 并执行它时,代码停止工作。我不知道我做错了什么。我试过改变文件夹的罐子,但它仍然不起作用。似乎问题在于 ubuntu 16.04 如何处理路由,因为在 Windows 中这可以正常工作。应用程序不会抛出异常

我获取 pdf 的方式对另一个应用程序执行相同的操作,但在其中我得到一个图像,它既可以在 jar 中工作,也可以在 ide 中执行。

 jbTree.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/tree.png")));

按钮代码

   if (Desktop.isDesktopSupported()) {
        try { 
            File myFile = new File (getClass().getResource("/help/help.pdf").toURI());
            Desktop.getDesktop().open(myFile);
        } catch (IOException | URISyntaxException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

解决方案是通过控制台运行应用程序。尝试以其他方式运行它是行不通的。

【问题讨论】:

  • 你的 pdf 也可能被打包到 jar 中了吗?
  • @RobinGreen 我不想按行读取文件。我想从我的应用程序中的按钮打开 pdf。这在 Windows 中对我有用。在 ubuntu 16.04 中它对我不起作用。
  • Desktop.getDesktop().open(myFile);打开任何其他文件?而不是只打印“异常”,您应该打印原始堆栈跟踪以查看实际消息是什么,“没有这样的文件或目录”(可能是大写/小写不匹配,Windows 马虎),缺少权限(不太可能,但可能)或者可能没有为桌面指定打开 PDF 的程序(不知道在哪里寻找它 - 可能是设置:Ubuntu 级别的默认应用程序)。并查看 Thecarismas 帖子,如何写 minimal reproducible example
  • 无法从 jar 中读取文件。您是否将 PDF 文件复制到 Ubuntu 系统并放在同一个地方?该目录甚至存在于 Ubuntu 系统上吗?
  • @pete “我认为问题在于 Windows 中的路径正常工作。但目前我使用的是 ubuntu 16.04,但它不起作用。” - 不。最有可能的问题是您的 pdf 也被打包到 jar 中。如果 PDF 在 jar 中,则它不是文件系统中的独立文件。另一方面,您的 Desktop.getDesktop().open(myFile) 确实希望文件系统中有一个独立的文件。

标签: java pdf jar ubuntu-16.04


【解决方案1】:

当您从 IDE 运行项目时,项目的根目录是 System.getProperty("user.dir"),例如,如果您的项目根文件夹是 PDFJar,它将查找 help.pdf PDFJar/src/project/help/ 文件夹中。

将项目构建为 jar 文件后,可执行 jar 将从 dist 或 bin 文件夹构建并执行,现在是 System.getProperty("user.dir")help.pdf 将在 dist/src/project/help/ 中查找文件夹。

您可以在 dist 或 bin 目录中创建包含 help.pdf 的文件夹 /src/project/help/ 或将 Jar 文件放在项目根目录中

已编辑

除了输入流之外,您无法将打包到 JAR 存档中的资源文件作为文件访问,它适用于您 IDE 的原因是因为该文件存在于 src 文件夹中执行目录是您的项目文件夹。您需要在 JAR 存档之外创建文件,然后将流读入其中,这样您就可以调用 Desktop 来打开它。

package stackoverflow;

import java.awt.Desktop;
import java.awt.HeadlessException;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author thecarisma
 */
public class StackOverflow {

    public void openHelpFile() {
        OutputStream outputStream = null;
        try {
            File outFile = new File("./help.pdf"); 
            outFile.createNewFile(); //create the file with zero byte in same folder as your jar file or a folder that exists
            InputStream in = getClass().getResourceAsStream("/help/help.pdf");
            outputStream = new FileOutputStream(outFile);
            int read = 0;
            //now we write the stream into our created help file
            byte[] bytes = new byte[1024];
            while ((read = in.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, read);
            }
            if (outFile.exists()) {
                String path= outFile.getAbsolutePath(); 
                JOptionPane.showMessageDialog(null, path);
                if (Desktop.isDesktopSupported()) {
                    JOptionPane.showMessageDialog(null, "Enter");
                    try { 
                        File myFile = new File (path);
                        Desktop.getDesktop().open(myFile);
                    } catch (IOException ex) {
                        JOptionPane.showMessageDialog(null, "Exception");
                    }
                }
            } else {
                JOptionPane.showMessageDialog(null, "Error Occur while reading file");
            }
        } catch (HeadlessException | IOException ex) {
            Logger.getLogger(StackOverflow.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                outputStream.close();
            } catch (IOException ex) {
                Logger.getLogger(StackOverflow.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        StackOverflow stackOverFlow = new StackOverflow();
        stackOverFlow.openHelpFile();
        //the bellow example works for file outside the JAR archive
        /**
        String path= new File("help.pdf").getAbsolutePath(); 
        JOptionPane.showMessageDialog(null, path);
        if (Desktop.isDesktopSupported()) {
            JOptionPane.showMessageDialog(null, "Enter");
            try { 
                File myFile = new File (path);
                Desktop.getDesktop().open(myFile);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "Exception");
            }
        } **/
    }

}

详情

当您的资源文件被打包到 JAR 存档中时,它不能作为文件访问,除非作为文件流。该文件的位置在 JAR 存档中是绝对位置,例如 /help/help.file。 如果您只想阅读资源的内容,例如 conf、xml、文本文件等,您可以将其读入 BufferReader

InputStream in = getClass().getResourceAsStream("/conf/conf.txt"); 
BufferedReader reader = new BufferedReader(new InputStreamReader(in));

否则,如果它是二进制文件,则需要在 jar 文件之外使用 0 byte 创建一个文件,然后将 JAR 存档中的资源流读取到创建的文件中。

注意:在从 JAR 存档中读取之前,您应该检查是否已经存在相同大小的帮助文件,以防止多次读取并跳过该过程以增加运行时间。创建文件时请注意,在 JAVA 中不存在的文件夹中创建文件是不可能的。

您可以使用存档管理器打开您的 .jar 文件,查看其结构

【讨论】:

  • 尝试将src/project/help/help.pdf 行更改为./help.pdf,然后将help.pdf 文件与jar 文件放在同一文件夹中
  • 您的代码在我的系统上运行良好,Jar 文件和 pdf 在同一位置
  • 我用的是 ubuntu 16.04,这是为什么呢?
  • 可能是这样。您应该尝试使用文件的绝对路径。您可以在终端中使用realpath help.pdf 获取文件绝对路径
  • 您的程序可以让我打开“./help.pdf”。也许皮特使用了一个文件 HELP.PDF 可以在 Windows 上运行,但不能在 linux 上运行?
猜你喜欢
  • 1970-01-01
  • 2014-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多