我正在尝试构建一个使用sox命令行实用程序将.dat文件转换为.wav文件的程序。
我的方法是创建一个.bat脚本并运行它。这在eclipse中有效但是当它在可执行jar文件中导出和打包时它会失败。这可能是由于两个问题所致。
第一个可能是从jar文件中访问sox.exe甚至是我自己的目录。
另一个是打包sox12181文件夹,其中包含sox需要运行的文件以及jar文件中的sox.exe本身。我已经搜索了如何打包它,并且只找到了在资源中打包图像的示例。
这是我的代码:
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);
}
}
以下是我程序中路径的屏幕截图:
我是stackoverflow平台的新手,所以如果有什么我应该改变的话请指出来。 谢谢!
答案 0 :(得分:1)
基于@zingerella和@howlger讨论我做了一些测试然后没有,不可能在jar中执行可执行文件,无论如何我做了一个解决方法,你可以看到它在docs工作。基本上它会将可执行文件复制到 SO 临时文件夹然后执行它。我的项目正在使用gradle,你也可以这样做this link,以下片段会认为你的可执行文件将在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();