1

我想验证一些东西,因为在我看来它是有道理的,但在 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

感谢您的时间。

4

1 回答 1

4

下面是一个 Java 程序示例,它通过其进程操作 C 程序(您也可以操作 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 发件人

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 类的同一文件夹中,编译并运行。“结束”命令将结束接收方和发送方。

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

于 2012-08-17T22:19:07.760 回答