Вопрос по console-application, java, command – Отправка команд в консольное приложение?

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

Спасибо за ваше время.

Попробуйте очистить поток:output.flush() после написания желаемой команды. davidbuzatto
Я положил это сразу после того, гдеoutput пишет, а результата пока нет. mattbdean
@davidbuzatto Нет, приложение не отвечает на него. mattbdean
Отправленные команды не работают? Попробуйте очистить выходной поток после написания команды (output.flush ()). davidbuzatto

Ваш Ответ

1   ответ
4

которая манипулирует C-программой посредством своего процесса (вы также можете манипулировать Java-программой). Я написал это несколько лет назад. Есть программа-получатель на C или Java и отправитель на Java. Взглянуть:

C Receiver

#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 (equal the C program)

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, скомпилируйте их и запустите. & Quot; конец & quot; Команда закончит получателя и отправителя.

Посмотрите в этой статье тоже:http://www.javaworld.com/jw-12-2000/jw-1229-traps.html

@whowantsakookie: Добро пожаловать! Я думаю, что код будет работать, так как я тестировал его несколько минут назад, но я изменил некоторые строки здесь без тестирования. Если это не сработает, думаю, вам будет легко это исправить. Дайте мне знать, если это сработало;)
Вау, спасибо за такой подробный ответ! Я попробую это как можно скорее. mattbdean

Похожие вопросы