使用桌面的默认应用程序打开存储在 jar 文件中的 PDF 文件
Opening a PDF file stored in a jar file with the desktop's default app
我的计算机科学课程的程序开发即将结束。但是,其中一项要求是在应用程序中包含用户手册。我在 Eclipse 的作品中将用户手册保存为 PDF space。
它存储在“/Documents/PDF Manual.pdf”下。我最初使用此代码:
URL url = getClass().getResource( fileSeparator + "Documents" + fileSeparator + "PDF Manual.pdf");
//fileSeparator = '/' on mac, & '\' on windows
File userManual = new File (url.toURI());
if (userManual.exists())
{
Desktop.getDesktop().open(userManual);
}
这在 运行 来自 eclipse 的项目时工作正常,但是当程序导出到 jar 文件时,URI returns 是一个非分层异常(如预期的那样)。我考虑过使用 url.toString(),使用 substring 和 replaceAll() 去除不需要的字符(space 为 %20),但是这产生了奇怪的结果,当然代码不会当它不是 jar 文件时不能正常工作。
我查看了 InputStream,但这仅用于读取文件,我无法使用桌面应用程序打开文件。
由于提交的过程,pdf 必须保存在项目文件夹中。
此外,我的代码必须与平台无关(或者至少,在 windows 和 mac 上工作),因此操作文件名变得更加复杂。有什么建议么?
编辑:
在@SubOptimal 的帮助下,这是我现在使用的代码:
String inputPdf = "Documents" + fileSeparator + "PDF Manual.pdf";
InputStream manualAsStream = getClass().getClassLoader().getResourceAsStream(inputPdf);
Path tempOutput = Files.createTempFile("TempManual", ".pdf");
tempOutput.toFile().deleteOnExit();
Files.copy(manualAsStream, tempOutput, StandardCopyOption.REPLACE_EXISTING);
File userManual = new File (tempOutput.toFile().getPath());
if (userManual.exists())
{
Desktop.getDesktop().open(userManual);
}
这适用于 mac。但是,在 windows 上,由于某些未知原因,manualAsStream 为空。
使用 getResourceAsStream 而不是 getResource
要在临时目录中写入,请使用 createTempFile
完整的工作示例。在 Windows 环境中测试。
文件结构
.\REPL.java
.\doc\manual.pdf
.\manifest.mf
REPL.java
package sub.optimal;
import java.io.InputStream;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.awt.Desktop;
public class REPL {
public static void main(String[] args) throws Exception {
String inputPdf = "doc/manual.pdf";
Path tempOutput = Files.createTempFile("TempManual", ".pdf");
tempOutput.toFile().deleteOnExit();
System.out.println("tempOutput: " + tempOutput);
try (InputStream is = REPL.class.getClassLoader().getResourceAsStream(inputPdf)) {
Files.copy(is, tempOutput, StandardCopyOption.REPLACE_EXISTING);
}
Desktop.getDesktop().open(tempOutput.toFile());
}
}
manifest.mf
Main-Class: sub.optimal.REPL
编译
javac -d . REPL.java
创建 JAR
mkdir dist\
jar cvfm dist/REPL.jar MANIFEST.MF sub/optimal/REPL.class doc/manual.pdf
执行 JAR
cd dist\
java -jar REPL.jar
我的计算机科学课程的程序开发即将结束。但是,其中一项要求是在应用程序中包含用户手册。我在 Eclipse 的作品中将用户手册保存为 PDF space。 它存储在“/Documents/PDF Manual.pdf”下。我最初使用此代码:
URL url = getClass().getResource( fileSeparator + "Documents" + fileSeparator + "PDF Manual.pdf");
//fileSeparator = '/' on mac, & '\' on windows
File userManual = new File (url.toURI());
if (userManual.exists())
{
Desktop.getDesktop().open(userManual);
}
这在 运行 来自 eclipse 的项目时工作正常,但是当程序导出到 jar 文件时,URI returns 是一个非分层异常(如预期的那样)。我考虑过使用 url.toString(),使用 substring 和 replaceAll() 去除不需要的字符(space 为 %20),但是这产生了奇怪的结果,当然代码不会当它不是 jar 文件时不能正常工作。
我查看了 InputStream,但这仅用于读取文件,我无法使用桌面应用程序打开文件。
由于提交的过程,pdf 必须保存在项目文件夹中。
此外,我的代码必须与平台无关(或者至少,在 windows 和 mac 上工作),因此操作文件名变得更加复杂。有什么建议么?
编辑:
在@SubOptimal 的帮助下,这是我现在使用的代码:
String inputPdf = "Documents" + fileSeparator + "PDF Manual.pdf";
InputStream manualAsStream = getClass().getClassLoader().getResourceAsStream(inputPdf);
Path tempOutput = Files.createTempFile("TempManual", ".pdf");
tempOutput.toFile().deleteOnExit();
Files.copy(manualAsStream, tempOutput, StandardCopyOption.REPLACE_EXISTING);
File userManual = new File (tempOutput.toFile().getPath());
if (userManual.exists())
{
Desktop.getDesktop().open(userManual);
}
这适用于 mac。但是,在 windows 上,由于某些未知原因,manualAsStream 为空。
使用 getResourceAsStream 而不是 getResource
要在临时目录中写入,请使用 createTempFile
完整的工作示例。在 Windows 环境中测试。
文件结构
.\REPL.java
.\doc\manual.pdf
.\manifest.mf
REPL.java
package sub.optimal;
import java.io.InputStream;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.awt.Desktop;
public class REPL {
public static void main(String[] args) throws Exception {
String inputPdf = "doc/manual.pdf";
Path tempOutput = Files.createTempFile("TempManual", ".pdf");
tempOutput.toFile().deleteOnExit();
System.out.println("tempOutput: " + tempOutput);
try (InputStream is = REPL.class.getClassLoader().getResourceAsStream(inputPdf)) {
Files.copy(is, tempOutput, StandardCopyOption.REPLACE_EXISTING);
}
Desktop.getDesktop().open(tempOutput.toFile());
}
}
manifest.mf
Main-Class: sub.optimal.REPL
编译
javac -d . REPL.java
创建 JAR
mkdir dist\
jar cvfm dist/REPL.jar MANIFEST.MF sub/optimal/REPL.class doc/manual.pdf
执行 JAR
cd dist\
java -jar REPL.jar