首页 文章

使用Java中的Octave

提问于
浏览
3

我需要在我的java应用程序中进行一些数值计算 . 出于几个原因,我决定将Octave用于此目的 .

我自己试着写一个简单的界面 . 由于Octave可以通过命令行使用,我只想通过ProcessBuilder启动Process并使用流写入/读取它 .

启动windwos终端并与之交互工作正常(使用cd,dir等命令) . 当我以这种方式开始八度音程时,一切似乎都运行良好,但经过一些测试我发现了两个问题:

  • 当我产生错误时,在我的java应用程序中,流关闭,我无法进一步交互,而不仅仅是获取消息并继续像八度音阶本身一样 .

  • 我可以写入这些流,就好像我直接通过命令行使用octave,但是当我想创建一个函数时,我总是得到“警告:函数名'someFunction'与函数文件名''”不一致,尽管我没有使用函数脚本文件 . 在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 's put method (to send a variable from java to octave), without any error message or warning. In debug mode I get 2440436 , which is probably caused by using the debug mode, so it doesn' t时,它会阻止任何进一步的(相关的)信息 .

作为我自己的界面的替代,如果有人知道如何使这个旧的工作再次起作用,对我来说也没关系 .

1 回答

  • 0

    因为我很忙,所以我完全忘记了这一点 . 我自己解决了这个问题,并获得了一个适用于界面的测试版 . 你可以找到here . 你会发现它很容易使用并提供所有基本功能(读写变量,调用函数) .

    如果你使用这个,请记住octave和java之间的数据交换使用标准文本流,因此大型矩阵和许多读/写操作可能会很慢 . 这也是由于数据在其ieee十六进制表示中读取/写入(默认情况下)( - >使用字符串字符进行二进制交换),但它可以防止舍入错误 . 只需尽可能多地保持数据的八度 .

    我希望这会有所帮助 . 随意使用它,只是让你的改进等也可以访问其他人 .

相关问题