我需要在我的java应用程序中进行一些数值计算 . 出于几个原因,我决定将Octave用于此目的 .
我自己试着写一个简单的界面 . 由于Octave可以通过命令行使用,我只想通过ProcessBuilder启动Process并使用流写入/读取它 .
启动windwos终端并与之交互工作正常(使用cd,dir等命令) . 当我以这种方式开始八度音程时,一切似乎都运行良好,但经过一些测试我发现了两个问题:
-
当我产生错误时,在我的java应用程序中,流关闭,我无法进一步交互,而不仅仅是获取消息并继续像八度音阶本身一样 .
-
我可以写入这些流,就好像我直接通过命令行使用octave,但是当我想创建一个函数时,我总是得到“警告:函数名'someFunction'与函数文件名''”不一致,尽管我没有使用函数脚本文件 . 在Octave,它的工作原理 .
这是我的测试代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
public class CLPI {
public static void main(String[] args) {
String func = "function a = func(b)" + System.lineSeparator()
+ "a = b;" + System.lineSeparator()
+ "endfunction" + System.lineSeparator();
ProcessBuilder builder = new ProcessBuilder(pathToOctaveCliExe,"--silent","--no-window-system");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
Process p = builder.start();
String s;
setUpProcessStreamThreads(p, System.out, System.err);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream ()));
writer.write(func);
writer.newLine();
writer.flush();
while((s = br.readLine()).compareToIgnoreCase("exit")!=0)
{
writer.write(s);
writer.newLine();
writer.flush();
}
writer.write("quit");
writer.newLine();
writer.flush();
p.destroy();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Closing program!");
}
public static void setUpProcessStreamThreads(final Process p, final PrintStream ops,PrintStream eps)
{
final InputStreamReader osr = new InputStreamReader(p.getInputStream());
final InputStreamReader esr = new InputStreamReader(p.getErrorStream());
Thread outputThread = new Thread(new Runnable() {
public void run() {
BufferedReader br = new BufferedReader(osr);
String line = null;
try {
while ((line = br.readLine()) != null) {
ops.println("pos: " + line);
}
System.out.println("End of OutputStream!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
Thread errorThread = new Thread(new Runnable() {
public void run() {
BufferedReader br = new BufferedReader(esr);
String line = null;
try {
while ((line = br.readLine()) != null) {
eps.println("pes: " + line);
}
System.out.println("End of ErrorStream!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
outputThread.setDaemon(true);
errorThread.setDaemon(true);
outputThread.start();
errorThread.start();
}
}
有人知道导致这些问题的原因以及如何解决这些问题吗?
最好的祝福
托森
ps:在尝试编写自己的界面之前,我找了一个现有的界面,找到了一个合适的界面,名为javaoctave(https://kenai.com/projects/javaoctave/pages/Home) . 在虚拟的Ubuntu上它可以工作,但是在我的系统(Windows 10)上,当我尝试使用OctaveEngine 's put method (to send a variable from java to octave), without any error message or warning. In debug mode I get 2440436 , which is probably caused by using the debug mode, so it doesn' t时,它会阻止任何进一步的(相关的)信息 .
作为我自己的界面的替代,如果有人知道如何使这个旧的工作再次起作用,对我来说也没关系 .
1 回答
因为我很忙,所以我完全忘记了这一点 . 我自己解决了这个问题,并获得了一个适用于界面的测试版 . 你可以找到here . 你会发现它很容易使用并提供所有基本功能(读写变量,调用函数) .
如果你使用这个,请记住octave和java之间的数据交换使用标准文本流,因此大型矩阵和许多读/写操作可能会很慢 . 这也是由于数据在其ieee十六进制表示中读取/写入(默认情况下)( - >使用字符串字符进行二进制交换),但它可以防止舍入错误 . 只需尽可能多地保持数据的八度 .
我希望这会有所帮助 . 随意使用它,只是让你的改进等也可以访问其他人 .