在 java 中执行外部命令行实用程序并将其打包到可运行的 jar 中
Executing external command line utility in java and packaging it into runnable jar
我正在尝试构建一个使用 sox 命令行实用程序将 .dat 文件转换为 .wav 文件的程序。
我的方法是创建一个 .bat 脚本并 运行 它。这在 eclipse 中有效,但在将其导出并打包到可执行 jar 文件中时失败。这可能是由于两个问题。
第一个可能是从 jar 文件中访问 sox.exe 甚至我自己的目录。
另一种方法是打包 sox12181 文件夹,其中包含 sox 需要的文件 运行 和 sox.exe 本身在 jar 文件中。我搜索了如何打包它,只在资源中找到了打包图像的示例。
这是我的代码:
package executableIII;
import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;
public class SoundManipulation {
public static void main(String[] args) throws IOException {
Queue<Double> queue1 = new LinkedList<>();
Queue<Double> queue2 = new LinkedList<>();
StringBuilder sb = new StringBuilder();
double sampleRate = 44100;
int m = (int) (sampleRate * 3);
int n = 700;
for (int i = 0; i < n; i++) {
queue1.add((Math.random() * 2) - 1);
}
queue2.add(0.0);
for (int i = 0; i < m; i++) {
double a = queue1.remove();
double b = queue2.remove();
double c = 0.99 * (a + b) / 2;
queue1.add(c);
queue2.add(a);
sb.append(i * (1 / sampleRate) + " " + c + "\n");
}
FileOutputStream fs = new FileOutputStream(System.getProperty("user.dir") + "\sox12181\generated.dat");
OutputStreamWriter out = new OutputStreamWriter(fs);
out.write("; Sample Rate 44100\n; Channels 1\n");
out.write(sb.toString());
out.close();
fs.close();
try {
FileOutputStream fsExec = new FileOutputStream("converter.bat");
OutputStreamWriter outExec = new OutputStreamWriter(fsExec);
outExec.write("cd " + System.getProperty("user.dir") + "\sox12181\nsox generated.dat generated.wav");
outExec.close();
fsExec.close();
} catch (IOException e) {
System.err.println(e);
}
File temp1 = new File("converter.bat");
Desktop.getDesktop().open(temp1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
File temp2 = new File("sox12181\generated.wav");
Desktop.getDesktop().open(temp2);
}
}
这是我程序中路径的屏幕截图:
我是 Whosebug 平台的新手,所以如果有任何我应该更改的地方,请指出。
谢谢!
根据@zingerella 和@howlger 的讨论,我做了一些测试,然后不行,不可能在 jar 中执行可执行文件,无论如何我为此做了一个解决方法,你可以看到它在 this link. Basically it will copy the executable to a SO temp folder then execute it. My project is using gradle anyway you can do it using eclipse同样,以下代码片段将认为您的可执行文件将位于 jar 根结构中
final InputStream in = Main.class.getResourceAsStream("/myprogram");
if (in == null) {
throw new RuntimeException("program not found");
}
final File tmpProgram = Files.createTempFile("mypgrogram", ".tmp").toFile();
Files.copy(in, tmpProgram.toPath(), StandardCopyOption.REPLACE_EXISTING);
tmpProgram.deleteOnExit();
tmpProgram.setExecutable(true);
final Process p = Runtime.getRuntime().exec(tmpProgram.getAbsolutePath());
System.out.println(p.waitFor());
for (int c; (c = p.getInputStream().read()) != -1; ) {
System.out.print((char) c);
}
System.out.println();
for (int c; (c = p.getErrorStream().read()) != -1; ) {
System.out.print((char) c);
}
System.out.println();
我正在尝试构建一个使用 sox 命令行实用程序将 .dat 文件转换为 .wav 文件的程序。
我的方法是创建一个 .bat 脚本并 运行 它。这在 eclipse 中有效,但在将其导出并打包到可执行 jar 文件中时失败。这可能是由于两个问题。
第一个可能是从 jar 文件中访问 sox.exe 甚至我自己的目录。
另一种方法是打包 sox12181 文件夹,其中包含 sox 需要的文件 运行 和 sox.exe 本身在 jar 文件中。我搜索了如何打包它,只在资源中找到了打包图像的示例。
这是我的代码:
package executableIII;
import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;
public class SoundManipulation {
public static void main(String[] args) throws IOException {
Queue<Double> queue1 = new LinkedList<>();
Queue<Double> queue2 = new LinkedList<>();
StringBuilder sb = new StringBuilder();
double sampleRate = 44100;
int m = (int) (sampleRate * 3);
int n = 700;
for (int i = 0; i < n; i++) {
queue1.add((Math.random() * 2) - 1);
}
queue2.add(0.0);
for (int i = 0; i < m; i++) {
double a = queue1.remove();
double b = queue2.remove();
double c = 0.99 * (a + b) / 2;
queue1.add(c);
queue2.add(a);
sb.append(i * (1 / sampleRate) + " " + c + "\n");
}
FileOutputStream fs = new FileOutputStream(System.getProperty("user.dir") + "\sox12181\generated.dat");
OutputStreamWriter out = new OutputStreamWriter(fs);
out.write("; Sample Rate 44100\n; Channels 1\n");
out.write(sb.toString());
out.close();
fs.close();
try {
FileOutputStream fsExec = new FileOutputStream("converter.bat");
OutputStreamWriter outExec = new OutputStreamWriter(fsExec);
outExec.write("cd " + System.getProperty("user.dir") + "\sox12181\nsox generated.dat generated.wav");
outExec.close();
fsExec.close();
} catch (IOException e) {
System.err.println(e);
}
File temp1 = new File("converter.bat");
Desktop.getDesktop().open(temp1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
File temp2 = new File("sox12181\generated.wav");
Desktop.getDesktop().open(temp2);
}
}
这是我程序中路径的屏幕截图:
我是 Whosebug 平台的新手,所以如果有任何我应该更改的地方,请指出。 谢谢!
根据@zingerella 和@howlger 的讨论,我做了一些测试,然后不行,不可能在 jar 中执行可执行文件,无论如何我为此做了一个解决方法,你可以看到它在 this link. Basically it will copy the executable to a SO temp folder then execute it. My project is using gradle anyway you can do it using eclipse同样,以下代码片段将认为您的可执行文件将位于 jar 根结构中
final InputStream in = Main.class.getResourceAsStream("/myprogram");
if (in == null) {
throw new RuntimeException("program not found");
}
final File tmpProgram = Files.createTempFile("mypgrogram", ".tmp").toFile();
Files.copy(in, tmpProgram.toPath(), StandardCopyOption.REPLACE_EXISTING);
tmpProgram.deleteOnExit();
tmpProgram.setExecutable(true);
final Process p = Runtime.getRuntime().exec(tmpProgram.getAbsolutePath());
System.out.println(p.waitFor());
for (int c; (c = p.getInputStream().read()) != -1; ) {
System.out.print((char) c);
}
System.out.println();
for (int c; (c = p.getErrorStream().read()) != -1; ) {
System.out.print((char) c);
}
System.out.println();