jjzjj

java - 命令行终端在进程上执行并从此进程输入交互

coder 2024-03-07 原文

<分区>

基本上,当我在我的 Java 应用程序上按下按钮时,我有一个运行的进程。 并且这个过程向操作系统的终端执行命令。 但有时此命令需要与用户进行交互。 我想知道是否可以在需要时让流程与用户进行交互?

我的代码:

File marsSimulator = new File("resources/mars_simulator/Mars4_5.jar");
if(marsSimulator.exists() && temp.exists()){
   String res="";
   try {
     Process p = Runtime.getRuntime().exec(new String[]{"java","-jar",marsSimulator.getAbsolutePath(),tempAssembly.getAbsolutePath()});
     p.waitFor();

     InputStream is = p.getInputStream();

     byte b[] = new byte[is.available()];
     is.read(b, 0, b.length); // probably try b.length-1 or -2 to remove "new-line(s)"

     res = new String(b);

   } catch (Exception ex) {
     ex.printStackTrace();
   }
}

此外,我忘了说该应用程序是使用 SWING 制作的,并且该过程的输出显示在 TextArea 上...我应该更改任何内容吗?

请注意,当与用户进行交互时,进程会阻塞。如果没有,进程不会阻塞!

在这种情况下我需要做什么(我不知道该怎么做)?

  1. 当流程需要交互时。我需要知道进程何时需要一些交互。
  2. 我需要以交互方式(逐行)获取流程生成的输出。

P.S.:对于想要了解生产线的人,我正在使用火星模拟器 ( http://courses.missouristate.edu/KenVollmar/MARS/ ) 并将 jar 应用程序发送到一个关联了 mips 汇编代码的进程中。


下一段代码正在与我的项目一起使用

希望对接下来的冒险家有所帮助!

感谢 Nicolas Filotto 对我的帮助。

我的类 ObservableStream:

class ObservableStream extends Observable {
  private final Queue<String> lines = new ConcurrentLinkedQueue<>();

  public void addLine(String line) {
    lines.add(line);
    setChanged();
    notifyObservers();
  }

  public String nextLine() {
    return lines.poll();
  }

  public String getLine(){return lines.peek();}
}

以及代码的另一部分:

Process p = Runtime.getRuntime().exec(new String[]{"java","-jar",marsSimulator.getAbsolutePath(),tempAssembly.getAbsolutePath()});

//This code does the interaction from the process with the GUI ! Implied, input interaction+output interaction from the process
ObservableStream out = new ObservableStream();
// Observer that simply sends to my external process line by line what we put in
// the variable output
PrintWriter writer = new PrintWriter(p.getOutputStream(), true);
out.addObserver(
  (o, arg) -> {
    ObservableStream stream = (ObservableStream) o;
    String line;
    while ((line = stream.nextLine()) != null) {
      writer.println(line);
    }
  }
);

ObservableStream input = new ObservableStream();
input.addObserver(
  (o, arg) -> {
    ObservableStream stream = (ObservableStream) o;
    String line;
    while ((line = stream.nextLine()) != null) {
      outputTextArea.appendText(line+"\n");
    }
  }
);

// The thread that reads the standard output stream of the external process
// and put the lines into my variable input
new Thread(
  () -> {
    try (BufferedReader reader = new BufferedReader(
      new InputStreamReader(p.getInputStream()))
    ) {
       String line;
       while ((line = reader.readLine()) != null) {
         input.addLine(line);
      }
    } catch (IOException e1) {
      e1.printStackTrace();
  }
 }
).start();


new Thread(
  ()->{
    while(p.isAlive()){
      String res = input.getLine();
      if(res!=null && res.equals("Enter integer value:")) {
        boolean integerIsRequested=true;
        Thread t=null;
        while(integerIsRequested){
          if(t==null) {
            t = new Thread(new Runnable() {
              public void run() {
                String test1 = JOptionPane.showInputDialog("Enter Integer value:");
                while(!test1.matches("^\\d+$")){
                  test1 = JOptionPane.showInputDialog("Error: Not a valid Integer.\nEnter a correct Integer value:");
                }
                Integer i = Integer.valueOf(test1);

                if (i != null) {
                  out.addLine(test1);
                }
              }
            });
            t.start();

          }
          if(!t.isAlive()){
            integerIsRequested=false;
          }
        }
      }
    }
    outputTextArea.appendText("Program executed\n");
  }
).start();

顺便说一下,这篇文章是独一无二的 Jarrod ;)

有关java - 命令行终端在进程上执行并从此进程输入交互的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  5. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  8. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  9. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  10. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

随机推荐