在java程序中编译,运行并获取输出java程序

时间:2016-05-13 18:47:22

标签: java ide output execute

你有编译器的代码,运行并从java程序中获取java程序的输出吗?

我在stackoverflow上发现了这个,但是,在string命令中,我必须要插入什么? java程序的路径?

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test {

public static void main(String[] args){
    Test t = new Test();

    t.start();
}

private void start(){
    String command = //Command to invoke the program

    ProcessBuilder pb = new ProcessBuilder(command);

    try{
        Process p = pb.start();

        InputStream stdout = p.getInputStream();
        InputStream stderr = p.getErrorStream();

        StreamListener stdoutReader = new StreamListener(stdout);
        StreamListener stderrReader = new StreamListener(stderr);

        Thread t_stdoutReader = new Thread(stdoutReader);
        Thread t_stderrReader = new Thread(stderrReader);

        t_stdoutReader.start();
        t_stderrReader.start();
    }catch(IOException n){
        System.err.println("I/O Exception: " + n.getLocalizedMessage());
    }
}

private class StreamListener implements Runnable{
    private BufferedReader Reader;
    private boolean Run;

    public StreamListener(InputStream s){
        Reader = new BufferedReader(new InputStreamReader(s));
        Run = true;
    }

    public void run(){
        String line;

        try{
            while(Run && (line = Reader.readLine()) != null){
                //At this point, a line of the output from the external process has been grabbed. Process it however you want.
                System.out.println("External Process: " + line);
            }
        }catch(IOException n){
            System.err.println("StreamListener I/O Exception!");
        }
    }
}
}

2 个答案:

答案 0 :(得分:0)

您的代码将用于从命令行调用javac,因此command最有可能是javac <someOptions> <someFileList>。相当难看的解决方法IMO。

相反,我建议使用Java Compiler API,它提供了java方式来编译源代码而不调用命令行:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

String options = "-Xlint:all";
int result = compiler.run(null , null , null , options , "somejavafile1.java" , "somejavafile2.java");

if(result == 0)
    System.out.println("Success");
else
    System.out.println("Error");

请注意,这只是一个如何调用编译器的简单示例。如果您想深入了解,请选择documentation,或者此tutorial应涵盖基础知识。

答案 1 :(得分:0)

感谢您的回答,

我用这个类来编译我的代码,这里是示例代码(在互联网上找到):

    import java.awt.BorderLayout;
    import java.awt.Font;
    import java.awt.EventQueue;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JLabel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.JButton;
    import javax.swing.SwingWorker;
    import javax.swing.border.EmptyBorder;

    import java.util.ArrayList;

    import java.net.URI;

    import java.io.ByteArrayOutputStream;
    import java.io.OutputStreamWriter;

    import javax.tools.ToolProvider;
    import javax.tools.JavaCompiler;
    import javax.tools.SimpleJavaFileObject;


    public class GuiCompiler extends JPanel {

      /** Instance of the compiler used for all compilations. */
      JavaCompiler compiler;

      /** The name of the public class.  For 'HelloWorld.java',
      this would be 'HelloWorld'. */
      JTextField name;
      /** The source code to be compiled. */
      JTextArea sourceCode;
      /** Errors and messages from the compiler. */
      JTextArea output;

      JButton compile;

      static int pad = 5;

      GuiCompiler() {
        super( new BorderLayout(pad,pad) );
        setBorder( new EmptyBorder(7,4,7,4) );
      }

      /** A worker to perform each compilation. Disables
      the GUI input elements during the work. */
      class SourceCompilation extends SwingWorker<String, Object> {
    @Override
    public String doInBackground() {
      return compileCode();
        }

    @Override
    protected void done() {
      try {
        enableComponents(true);
      } catch (Exception ignore) {
      }
    }
      }

      /** Construct the GUI. */
      public void initGui() {
    JPanel input = new JPanel( new BorderLayout(pad,pad) );
    Font outputFont = new Font("Monospaced",Font.PLAIN,12);

    sourceCode = new JTextArea("Paste code here..", 15, 60);
    sourceCode.setFont( outputFont );
    input.add( new JScrollPane( sourceCode ),
      BorderLayout.CENTER );
    sourceCode.select(0,sourceCode.getText().length());

    JPanel namePanel = new JPanel(new BorderLayout(pad,pad));
    name = new JTextField(15);
    name.setToolTipText("Name of the public class");
    namePanel.add( name, BorderLayout.CENTER );
    namePanel.add( new JLabel("Class name"), BorderLayout.WEST );

    input.add( namePanel, BorderLayout.NORTH );

    compile = new JButton( "Compile" );
    compile.addActionListener( new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
          (new SourceCompilation()).execute();
        }
      } );
    input.add( compile, BorderLayout.SOUTH );

    this.add( input, BorderLayout.CENTER );

    output = new JTextArea("", 5, 40);
    output.setFont( outputFont );
    output.setEditable(false);
    this.add( new JScrollPane( output ), BorderLayout.SOUTH );
  }

  /** Compile the code in the source input area. */
  public String compileCode() {
    output.setText( "Compiling.." );
    enableComponents(false);
    String compResult = null;
    if (compiler==null) {
      compiler = ToolProvider.getSystemJavaCompiler();
    }
    if ( compiler!=null ) {
      String code = sourceCode.getText();
      String sourceName = name.getText().trim();
      if ( sourceName.toLowerCase().endsWith(".java") ) {
        sourceName = sourceName.substring(
          0,sourceName.length()-5 );
      }
      JavaSourceFromString javaString = new JavaSourceFromString(
        sourceName,
        code);
      ArrayList<JavaSourceFromString> al =
        new ArrayList<JavaSourceFromString>();
      al.add( javaString );

      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      OutputStreamWriter osw = new OutputStreamWriter( baos );

      JavaCompiler.CompilationTask task = compiler.getTask(
        osw,
        null,
        null,
        null,
        null,
        al);

      boolean success = task.call();

      output.setText( baos.toString().replaceAll("\t", "  ") );

      compResult = "Compiled without errors: " + success;

      output.append( compResult );
      output.setCaretPosition(0);
    } else {
      output.setText( "No compilation possible - sorry!" );
      JOptionPane.showMessageDialog(this,
        "No compiler is available to this runtime!",
        "Compiler not found",
        JOptionPane.ERROR_MESSAGE
        );
      System.exit(-1);
    }
    return compResult;
  }

  /** Set the main GUI input components enabled
  according to the enable flag. */
  public void enableComponents(boolean enable) {
    compile.setEnabled(enable);
    name.setEnabled(enable);
    sourceCode.setEnabled(enable);
  }

  public static void main(String[] args) throws Exception {

    Runnable r = new Runnable() {
      public void run() {
        JFrame f = new JFrame("SSCCE text based compiler");
        f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        GuiCompiler compilerPane = new GuiCompiler();
        compilerPane.initGui();

        f.getContentPane().add(compilerPane);

        f.pack();
        f.setMinimumSize( f.getSize() );
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    };
    EventQueue.invokeLater(r);
  }
}
class JavaSourceFromString extends SimpleJavaFileObject {
  /**
  * The source code of this "file".
  */
  final String code;

  /**
  * Constructs a new JavaSourceFromString.
  * @param name the name of the compilation unit represented
    by this file object
  * @param code the source code for the compilation unit
    represented by this file object
  */
  JavaSourceFromString(String name, String code) {
    super(URI.create(
      "string:///" +
      name.replace('.','/') +
      Kind.SOURCE.extension),
      Kind.SOURCE);
    this.code = code;
  }

  @Override
  public CharSequence getCharContent(boolean ignoreEncodingErrors) {
    return code;
  }
}

但是在编译之后,我必须运行它并从相同的代码获取输出,我该怎么办? :(