繁体   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