在我的代码中有以下函数。
public static void runExecutable(String filePath, String command, boolean commandLine, boolean wait) {
InputStream inputStream = CommonMethods.class.getClassLoader().getResourceAsStream(filePath);
String tempFileSuffix = "";
switch (CommonMethods.getOperatingSystem()) {
case "Windows":
tempFileSuffix = ".exe";
break;
case "Linux":
case "Mac":
tempFileSuffix = ".bin";
break;
}
File tempFile;
try {
tempFile = File.createTempFile("AutoFPCurator", tempFileSuffix);
} catch (IOException e) {
new ErrorDialog(e);
return;
}
try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
} catch (IOException e) {
new ErrorDialog(e);
return;
}
String cmdProgram = "";
String cFlag = "-c";
switch (CommonMethods.getOperatingSystem()) {
case "Windows":
cmdProgram = "cmd.exe";
cFlag = "/c";
break;
case "Mac":
cmdProgram = "sh";
break;
case "Linux":
cmdProgram = "bash";
break;
default:
return;
}
ProcessBuilder processBuilder = !commandLine ? new ProcessBuilder(tempFile.getAbsolutePath(), command)
: new ProcessBuilder(cmdProgram, cFlag, tempFile.getAbsolutePath(), command);
processBuilder.redirectErrorStream(true);
Process process;
try {
process = processBuilder.start();
} catch (IOException e) {
new ErrorDialog(e);
return;
}
if (!wait) {
return;
}
try {
process.waitFor();
} catch (InterruptedException e) {
new ErrorDialog(e);
}
}
这段代码被设计为运行src/main/resources/中的可执行文件,正如它所指定的那样,但是它特别用于将文件夹压缩成7z文件(使用其src/main/resources目录中的独立7z可执行文件)。我使用可执行文件是因为为Java设计的7Z压缩算法(比如Apache Commons的),不像可执行文件那样,按照我需要的方式压缩它。我下载了Linux 7z可执行文件,解压缩它,并在程序中使用7zz)。当我这样称呼它时:
switch (CommonMethods.getOperatingSystem()) {
case "Windows":
exeString = "programs/7zip/7za.exe";
break;
case "Mac":
exeString = "programs/7zip/7zzmac";
break;
case "Linux":
exeString = "programs/7zip/7zznux";
break;
default:
System.out.println(commonStrs.get("unsupportedOS"));
return;
}
CommonMethods.runExecutable(exeString, args, true, true);
它在Windows上工作,但我在Linux上试过,它不工作。我一直在努力找出问题所在参数是有效的,它看起来确实在运行,但它只是不压缩文件夹。我运行了原始参数,该函数将自己构建到Linux终端中,它说“Permission denied”,以响应我试图访问tmp文件夹(临时7zip可执行文件存储的地方)。我试着把它存储在一个完全可以访问的备用位置,但无济于事。
TL;DR,我如何在Linux(和Mac的扩展,也许?))?需要说明的是,这在Windows上有效。
1条答案
按热度按时间wgeznvg71#
在macOS(Ventura 13.4)上,我下载了
7zz
的可执行文件。然后我写了一个快速程序来验证我可以通过ProcessBuilder
直接运行可执行文件(不需要sh
)。这是成功的。然后,我将
7zz
添加到应用程序资源中,并将其解压缩到临时文件中。由于文件不可执行(File#canExecute
为false
),因此失败。然后,基于How do I programmatically change file permissions?,我修改了临时文件的执行属性(在它被提取之后),这是成功的
您可能会发现首先在每个平台上找到一个工作解决方案,然后围绕这些需求设计您的解决方案更容易,也许有一个基于平台生成
ProcessBuilder
的工厂作为一个想法。