[英]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.