使用来自 Java 的 Octave
Using Octave from Java
我需要在我的 java 应用程序中进行一些数值计算。出于几个原因,我决定为此目的使用 Octave。
我试着自己写了一个简单的界面。由于 Octave 可以通过命令行使用,我想通过 ProcessBuilder 启动一个进程并使用流 write/read 来简单地做到这一点。
启动 windwos 终端并与其交互工作正常(使用 cd、dir 等命令)。当我以这种方式开始八度时,一切似乎都很好,但经过一些测试后我发现了两个问题:
当我产生错误时,在我的 java 应用程序中,流关闭并且我无法进行任何进一步的交互,而不仅仅是获取消息并像八度本身一样继续前进。
我几乎可以像直接通过命令行使用 Octave 一样写入这些流,但是当我想创建一个函数时,我总是得到 "warning: function name 'someFunction' does not agree with function filename '' ",尽管我不使用函数脚本文件。在 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 的 put 方法(将变量从 java 发送到 Octave)时它会阻塞,没有任何错误信息或警告。在调试模式下,我得到 "error: load: failed to load matrix constant",这可能是使用调试模式引起的,因此它没有提供任何进一步的(相关)信息。
或者我自己的界面,如果有人知道如何让这个旧界面再次工作,那对我来说也很好。
忙的时候完全忘记了这件事。我自己解决了它并获得了一个界面的工作测试版。你可以找到它 here。您会发现它不完整且没有很好的文档记录,但它非常易于使用并提供所有基本功能(读取和写入变量、调用函数)。
如果您使用它,请记住八度和 java 之间的数据交换使用标准文本流,因此对于大矩阵和许多 read/write 操作来说可能很慢。这也是由于数据在其 ieee 十六进制表示中为 read/written(默认情况下)(-> 使用字符串字符的二进制交换),但它可以防止舍入错误。尽可能将数据保持在八度范围内。
希望对您有所帮助。请随意使用它,让其他人也可以访问您的改进等。
我需要在我的 java 应用程序中进行一些数值计算。出于几个原因,我决定为此目的使用 Octave。
我试着自己写了一个简单的界面。由于 Octave 可以通过命令行使用,我想通过 ProcessBuilder 启动一个进程并使用流 write/read 来简单地做到这一点。
启动 windwos 终端并与其交互工作正常(使用 cd、dir 等命令)。当我以这种方式开始八度时,一切似乎都很好,但经过一些测试后我发现了两个问题:
当我产生错误时,在我的 java 应用程序中,流关闭并且我无法进行任何进一步的交互,而不仅仅是获取消息并像八度本身一样继续前进。
我几乎可以像直接通过命令行使用 Octave 一样写入这些流,但是当我想创建一个函数时,我总是得到 "warning: function name 'someFunction' does not agree with function filename '' ",尽管我不使用函数脚本文件。在 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 的 put 方法(将变量从 java 发送到 Octave)时它会阻塞,没有任何错误信息或警告。在调试模式下,我得到 "error: load: failed to load matrix constant",这可能是使用调试模式引起的,因此它没有提供任何进一步的(相关)信息。
或者我自己的界面,如果有人知道如何让这个旧界面再次工作,那对我来说也很好。
忙的时候完全忘记了这件事。我自己解决了它并获得了一个界面的工作测试版。你可以找到它 here。您会发现它不完整且没有很好的文档记录,但它非常易于使用并提供所有基本功能(读取和写入变量、调用函数)。
如果您使用它,请记住八度和 java 之间的数据交换使用标准文本流,因此对于大矩阵和许多 read/write 操作来说可能很慢。这也是由于数据在其 ieee 十六进制表示中为 read/written(默认情况下)(-> 使用字符串字符的二进制交换),但它可以防止舍入错误。尽可能将数据保持在八度范围内。
希望对您有所帮助。请随意使用它,让其他人也可以访问您的改进等。