将命令发送到控制台应用程序?

时间:2012-08-17 21:58:58

标签: java command console-application

我想验证一些东西,因为在我看来它是有意义的,但在Java中,它不起作用。

我正在尝试通过我的应用程序运行另一个Jar文件。准确地说是Minecraft服务器。我已经掌握了所有基础知识(使用ProcessBuilder,使用参数执行,等待退出代码等),但有一点我无法弄清楚。将命令发送到应用程序。这是我CommandLineSender课程的一部分:

public class CommandLineSender extends Thread {

    private BufferedWriter output;
    private InputStream source;  // Set to System.in when creating the object
    private boolean stopRequested;

    public CommandLineSender(Process sendTo, InputStream source) {
        this.output = new BufferedWriter(new OutputStreamWriter(sendTo.getOutputStream()));
        this.source = source;
        System.out.println("Source InputStream initiated: " + source.toString());
        this.stopRequested = false;
    }

    @Override
    public void run() {
        System.out.println("Run called.");
        Scanner cmdScanner = new Scanner(source);
        while (cmdScanner.hasNextLine() && !stopRequested) {
            System.out.println("Has next line");
            String msg = cmdScanner.nextLine();
            write(msg);
            System.out.println("Wrote: " + msg);
        }

        // Close the scanner and BufferedWriter

        System.out.println("Closed.");

    }

    // Other various methods

    protected void write(String msg) {
        try {
            output.write(msg);
        } catch (IOException e) {
            System.err.println("Unable to write message because of an unhandled IOException: " + e.getMessage());
        }

    }

我得到的输出是:

(Default Minecraft server output)

help  // My command
Has next line
Wrote: help

这可能无关紧要,但我正在使用这些参数执行我的服务器:

java -Xmx1024M -Xms1024M -jar (path to server jar) nogui

感谢您的时间。

1 个答案:

答案 0 :(得分:4)

这是一个通过其进程操作C程序的Java程序示例(您也可以操作Java程序)。几年前我写过这篇文章。有接收者程序用C或Java,发件人用Java。看看:

C接收器

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

int main() {

    char message[50] = {0};

    while ( true ) {

        gets( message );
        printf( "string \"%s\" received...\n", message );

        // forces the streams to flush
        fflush( stdout );
        fflush( stderr ); // the java program will not write in the error stream, so this line (for this example) is irrelevant

        // if the java program send a "end" command (message here) it will break the while
        if ( !strcmp( "end", message ) ) {
            break;
        }

    }

    return 0;

}

Java Receiver(等于C程序)

import java.util.*;

public class MessageReceiver {

    public static void main( String[] args ) {

        Scanner scan = new Scanner( System.in );

        while ( true ) {

            String message = scan.nextLine();
            System.out.printf( "string \"%s\" received...\n", message );

            System.out.flush();
            System.err.flush();

            if ( message.equals( "end" ) ) {
                break;
            }

        }

    }

}

Java Sender

import java.io.*;
import java.util.*;

public class Sender {

    /**
     * @param args the command line arguments
     */
    public static void main( String[] args ) {
        new Sender().execute();
    }

    public void execute() {

        try {

            // executes the command (the C executable)
            Process process = Runtime.getRuntime().exec( "MessageReceiver.exe" );

            // or, executes the MessageReceiver class
            //Process process = Runtime.getRuntime().exec( "java MessageReceiver" );

            // create the stream gobblers, one for the input stream and one for the
            // error stream. these gobblers will consume these streams.
            StreamGobbler sgInput = new StreamGobbler(
                    process.getInputStream(), "input" );
            StreamGobbler sgError = new StreamGobbler(
                    process.getErrorStream(), "error" );

            // creates a thread for each stream gobbler and start them
            new Thread( sgInput ).start();
            new Thread( sgError ).start();

            // creates a PrintWriter using the process output stream
            PrintWriter writer = new PrintWriter( process.getOutputStream() );

            // preparing to read user input
            Scanner scan = new Scanner( System.in );

            while ( true ) {

                System.out.println( "Send a command: " );
                String command = scan.nextLine();

                // sends the command to the process
                // simulating an user input (note the \n)
                writer.write( command );
                writer.write( "\n" );
                writer.flush();

                // if the command is end, finalizes this app too
                if ( command.equals( "end" ) ) {
                    break;
                }

            }

        } catch ( IOException ioe ) {
            ioe.printStackTrace();
        }

    }

    /**
     * Threads to consume the process streams.
     * Based in the implementation presented here:
     * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
     *
     * @author David Buzatto
     */
    private class StreamGobbler implements Runnable {

        private InputStream is;
        private String type;
        private FileWriter fw;

        public StreamGobbler( InputStream is, String type ) {
            this.is = is;
            this.type = type;
        }

        public StreamGobbler( InputStream is, String type, File file )
                throws IOException {
            this.is = is;
            this.type = type;
            this.fw = new FileWriter( file );
        }

        @Override
        public void run() {
            try {
                InputStreamReader isr = new InputStreamReader( is );
                BufferedReader br = new BufferedReader( isr );
                String line = null;
                while ( ( line = br.readLine() ) != null ) {
                    if ( fw != null ) {
                        fw.write( line + "\n" );
                    } else {
                        System.out.println( type + ">" + line );
                    }
                }
                if ( fw != null ) {
                    fw.close();
                }
            } catch ( IOException ioe ) {
                ioe.printStackTrace();
            }
        }
    }

}

要运行代码,请编译C程序或MessageReceiver类。将可执行文件放在Sender类的同一文件夹中,编译并运行。 “end”命令将完成接收者和发送者。

请看一下这篇文章:http://www.javaworld.com/jw-12-2000/jw-1229-traps.html