我正在使用mkvmerge将avi文件和ass文件合并到mkv文件中。
我当前有可执行文件和java文件的目录位于名为auto-mkvmerge
的文件夹中。
当我在命令行中使用以下内容时,它正常工作,mkvmerge.exe -o ../auto-done/098.mkv ../auto-vid/098.avi ../auto-sub/098.ass
我输出正确。
当我运行我的java代码时,它不起作用,并给我一个错误。
我的java代码。 Main.java
import java.io.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
File vidDir = new File(args[0]);
File subDir = new File(args[1]);
File outDir = new File(args[2]);
String[] vids = vidDir.list();
String[] subs = subDir.list();
for(int i = 0; i < vids.length; i++) {
int r = mergeAviAndAss(vids[i], subs[i], args[2]);
}
}
private static int mergeAviAndAss(String aviFileName, String assFileName, String doneDir) {
try {
ProcessBuilder pb = new ProcessBuilder("mkvmerge.exe", "-o", doneDir + "/" + aviFileName.substring(0, aviFileName.length() - 4) + ".mkv", "\"" + aviFileName + "\"", "\"" + assFileName + "\"");
Process p = pb.start();
InputStream inputStream = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line;
while((line = br.readLine()) != null)
System.out.println(line);
return p.waitFor();
} catch(IOException e) {
e.printStackTrace();
} catch(InterruptedException e) {
e.printStackTrace();
}
return -1;
}
}
当我使用以下行执行它时(在编译我的java代码之后):java Main ../auto-vid ../auto-sub ../auto-done > log.txt
mkvmerge v6.6.0 ('The Edge Of The In Between') built on Dec 1 2013 17:55:00
Error: The file '098.avi' could not be opened for reading: open file error.
mkvmerge v6.6.0 ('The Edge Of The In Between') built on Dec 1 2013 17:55:00
Error: The file '099.avi' could not be opened for reading: open file error.
mkvmerge v6.6.0 ('The Edge Of The In Between') built on Dec 1 2013 17:55:00
Error: The file '100.avi' could not be opened for reading: open file error.
mkvmerge v6.6.0 ('The Edge Of The In Between') built on Dec 1 2013 17:55:00
Error: The file '101.avi' could not be opened for reading: open file error.
mkvmerge v6.6.0 ('The Edge Of The In Between') built on Dec 1 2013 17:55:00
Error: The file '102.avi' could not be opened for reading: open file error.
mkvmerge v6.6.0 ('The Edge Of The In Between') built on Dec 1 2013 17:55:00
Error: The file '103.avi' could not be opened for reading: open file error.
我的代码或我编写代码的方式有问题,因为如果我在命令行输入代码时它正常工作,它应该在我的java代码中工作。
答案 0 :(得分:0)
我认为您可以使用Runtime.exec(java.lang.String[])
并在Windows上使用Runtime.getRuntime().exec("cmd \c here goes your command")
以使用指定的命令启动其控制台。
编辑:要运行所需的命令,请使用Runtime.getRuntime().exec("here goes your command")
答案 1 :(得分:0)
这是一个路径问题。你可以:
如果这个选项有效,你可以知道还会有一个相对路径可以工作,概率为java Main ../auto-done/098.mkv ../auto-done/098.avi ...
答案 2 :(得分:0)
这是由techurbana指出的路径问题。
您需要在启动流程之前通过调用流程构建器的.directory(String)方法来设置流程上的工作目录。您需要为其提供应用程序的根目录。
您可以通过以下方式获取JAVA可执行文件的当前工作目录(可能是您存储mkvmerg.exe的位置):
File dir = new File("");
dir.getAbsolutePath();
如果您的mkvmerg.exe实用程序在您的系统中有一个类路径条目(无论如何在Windows上),您应该能够从任何目录运行mkvmerg.exe。
然后,如果您希望mkvmerge在某个子文件夹中处理文件,请执行FolderA:
File subDir = new File(dir, "FolderA");
subDir.getAbsolutePath();
尝试在运行时打印出用于控制台的所有路径,以验证文件和可执行文件的路径是否正确,并且调试应该很快。
请查看以下管理路径的示例。它只是用记事本打开当前目录中的文件,但几乎就是你想要做的。要运行它,请将一些路径作为参数传递给main()。
编辑 - 我刚刚意识到我从未真正使用传递给应用程序的路径,只能在java可执行文件的当前目录中查找第一个文件,但是你明白了。
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
public class MainTest {
public static void main(String[] args) {
// passes in a directory
if (args.length > 0) {
doSomethingWithCMD(args[0]);
}
}
public static void doSomethingWithCMD(String filesDir) {
try {
File currDir = new File("");
// this is a bit weird, but listFiles didnt return anything without
// this next line.
currDir = new File(currDir.getAbsolutePath());
System.out.println(currDir.getAbsolutePath());
// build our command with a string builder
StringBuilder sb = new StringBuilder();
// get the list of files
File[] files = currDir.listFiles();
// if there are no files this will be null so check first
if (!(files == null)) {
for (File f : files) {
if (f.isFile()) {
sb.append("notepad ");
sb.append("\"" + f.getAbsolutePath());
sb.append("\"");
break;
}
}
}
// create our process builder
// first with no working dir & absolute paths
ProcessBuilder pb = new ProcessBuilder(sb.toString());
Process p = pb.start();
InputStream inputStream = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
inputStream));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
// cleanup
try {
inputStream.close();
}
catch (Exception ignore) {
}
try {
br.close();
}
catch (Exception ignore) {
}
sb = new StringBuilder();
// now we rebuild our command using relative paths instead of
// absolute ones
if (!(files == null)) {
for (File f : files) {
if (f.isFile()) {
sb.append("notepad ");
sb.append("\"" + f.getName());
sb.append("\"");
break;
}
}
}
pb = new ProcessBuilder(sb.toString());
//set the working directory
pb.directory(currDir);
p = pb.start();
inputStream = p.getInputStream();
br = new BufferedReader(new InputStreamReader(inputStream));
line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}