[英]Using Octave from Java
我需要在我的 java 应用程序中进行一些数值计算。 出于多种原因,我决定为此使用 Octave。
我试着自己写一个简单的界面。 由于 Octave 可以通过命令行使用,因此我想通过 ProcessBuilder 启动一个进程并使用流对其进行写入/读取。
启动windwos 终端并与之交互工作正常(使用cd、dir 等命令)。 当我以这种方式开始八度时,一切似乎都很好,但经过一些测试后,我发现了两个问题:
当我产生错误时,在我的 Java 应用程序中,流关闭,我无法进一步交互,而不仅仅是获取消息并像八度本身一样继续前进。
我几乎可以像直接通过命令行使用八度音程一样写入这些流,但是当我想创建一个函数时,我总是收到“警告:函数名称‘someFunction’与函数文件名‘’不一致”,尽管我' 没有使用函数脚本文件。 在八度中它有效。
这是我的测试代码:
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 的 put 方法(将变量从 java 发送到 Octave)时它会阻塞,没有任何错误消息或警告。 在调试模式下,我收到“错误:加载:无法加载矩阵常量”,这可能是由于使用调试模式引起的,因此它没有提供任何进一步的(相关)信息。
或者我自己的界面,如果有人知道如何让这个旧界面再次工作,那对我来说也很好。
因为忙,我完全忘记了这件事。 我自己解决了这个问题,并获得了一个界面的可用测试版。 你可以在这里找到它。 您将看到它不完整且没有很好的文档记录,但它非常易于使用并提供所有基本功能(读取和写入变量、调用函数)。
如果您使用它,请记住,octave 和 java 之间的数据交换使用标准文本流,因此对于大矩阵和许多读/写操作可能会很慢。 这也是因为数据在其 ieee 十六进制表示中被读取/写入(默认情况下)(-> 使用字符串字符的二进制交换),但它可以防止舍入错误。 只需将您的数据尽可能保持在八度音程。
我希望这会有所帮助。 随意使用它,只需让其他人也可以访问您的改进等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.