2011-03-30 49 views
0

我在線程(RunFile)中運行進程,並且我有2個線程用於使用stdin和stdout(WriteStdin,ReadStdout)工作。當進程只寫入標準輸出而不使用標準輸入時,一切都是正確的。 當進程向stdout寫入任何內容並等待stdin輸入時,ReadStdout不會寫入任何內容,直到WriteStdin不向變量發送變量爲止。當進程退出時,則ReadStdout會打印所有內容。在這種情況下,我需要ReadStdout做出第一個列表,然後進程等待來自stdin的輸入。java:在同一時間使用stdin/stdout進程

該類創建一個正在運行該進程的線程,並創建線程ReadStdout和WriteStdin。

package bin; 

import java.io.IOException; 
import javax.swing.JTextArea; 

public class RunFile implements Runnable{ 

    public Thread program = null; 
    public Process process = null; 

    private JTextArea console; 

    public RunFile(JTextArea cons){ 
     console = cons; 

     program = new Thread(this); 
     program.start(); 
    } 

    public void run() {  
     try { 
      String exe = "path to executable file"; 

      process = Runtime.getRuntime().exec(exe); 

      ReadStdout read = new ReadStdout(process); 
      WriteStdin write = new WriteStdin(process, console); 

      process.waitFor(); 

      write.write.stop(); 
      read.read.stop(); 

      System.out.println("\nExit value: " + process.exitValue() + "\n"); 
     } 
     catch (InterruptedException e) {} 
     catch (IOException e1) {}  
    } 
} 

這個類創建一個線程,它與進程的stdin一起工作。 主題是永久停權,就會觸發只有在那一刻有東西可寫,以標準輸入

package bin; 

import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import javax.swing.JTextArea; 
import javax.swing.text.BadLocationException; 

class WriteStdin implements Runnable{ 

    private Process process = null; 
    private JTextArea console = null; 
    public Thread write = null; 
    private String input = null; 
    private BufferedWriter writer = null; 

    public WriteStdin(Process p, JTextArea t){ 

     process = p; 
     console = t; 
     writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 

     write = new Thread(this); 
     write.start(); 

     console.addKeyListener(new java.awt.event.KeyAdapter() { 
      public void keyTyped(java.awt.event.KeyEvent e){ 

       //save the last lines for console to variable input 
       if(e.getKeyChar() == '\n'){ 

        try {      
         int line = console.getLineCount() -2; 
         int start = console.getLineStartOffset(line); 
         int end = console.getLineEndOffset(line); 

         input = console.getText(start, end - start); 

         write.resume(); 

        } catch (BadLocationException e1) {} 
       } 
      } 
     }); 
    } 


    public void run(){ 
     write.suspend(); 
     while(true){ 
      try { 
       //send variable input in stdin of process 
       writer.write(input); 
       writer.flush(); 

      } catch (IOException e) {} 
      write.suspend(); 
     } 
    } 
} 

這個類來創建一個線程,這與工藝的標準輸出工作

package bin; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import javax.swing.JTextArea; 
import javax.swing.text.BadLocationException; 

class ReadStdout implements Runnable{ 

    public Thread read = null; 
    private BufferedReader reader = null; 
    private Process process = null; 

    public ReadStdout(Process p){ 

     process = p; 
     reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 

     read = new Thread(this); 
     read.start(); 
    } 

    public void run() { 
     while(true){ 
     try { 
       String line = reader.readLine(); 
       if(line != null) 
        System.out.println (line); 
     } catch (IOException e) {} 
     }  
    } 
} 

這是一個例子源(在創建過程中

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 

    for(int i=0; i<10; i++) 
    printf("%d\n", i); 

    char a[10]; 
    scanf("%s", a); 
    printf("%s\n",a); 

    for(int i=0; i<10; i++) 
    printf("%d\n", i); 

    return 0; 
} 
+0

這是需要穿過的很多代碼。將其縮小到可以幫助人們瞭解您的問題的最小部分。 – 2011-03-30 22:20:24

+2

我強烈建議不要使用'thread.stop()',而是簡單地告訴你的runnable不要再運行了(考慮一個'布爾運行'成員變量。) – corsiKa 2011-03-30 22:28:16

+0

對'thread.stop'警告+1。對於任何沒有閱讀過的人,javadoc會說「不推薦」,這種方法本質上是不安全的。使用Thread.stop停止線程會導致它解鎖所有已鎖定的監視器(作爲未經檢查的ThreadDeath異常的自然結果如果之前由這些監視器保護的任何對象處於不一致狀態,則損壞的對象對其他線程變得可見,這可能導致任意行爲。「 – 2011-03-31 00:55:49

回答

0

時,我有一個解決方案,我使用的程序C),在Linux中程序必須創建這樣的:

String exe = "absolute path to executable file"; 
ProcessBuilder builder = new ProcessBuilder(); 
builder.command().add("bash"); 
builder.command().add("-c"); 
builder.command().add("stdbuf -o0 " + exe); 
builder.redirectErrorStream(true); 
Process process = builder.start(); 

Stdout沒有被緩衝,我的程序工作。

相關問題