簡體   English   中英

使用 Java 中的 Octave

[英]Using Octave from Java

我需要在我的 java 應用程序中進行一些數值計算。 出於多種原因,我決定為此使用 Octave。

我試着自己寫一個簡單的界面。 由於 Octave 可以通過命令行使用,因此我想通過 ProcessBuilder 啟動一個進程並使用流對其進行寫入/讀取。

啟動windwos 終端並與之交互工作正常(使用cd、dir 等命令)。 當我以這種方式開始八度時,一切似乎都很好,但經過一些測試后,我發現了兩個問題:

  1. 當我產生錯誤時,在我的 Java 應用程序中,流關閉,我無法進一步交互,而不僅僅是獲取消息並像八度本身一樣繼續前進。

  2. 我幾乎可以像直接通過命令行使用八度音程一樣寫入這些流,但是當我想創建一個函數時,我總是收到“警告:函數名稱‘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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM