1

頭の中では理にかなっていますが、Java では機能しないので、何かを検証したいと思います。

アプリケーションで別の Jar ファイルを実行しようとしています。正確には Minecraft サーバーです。すべての基本 ( の使用ProcessBuilder、引数を使用した実行、終了コードの待機など) は完了しましたが、理解できないことが 1 つあります。アプリケーションにコマンドを送信します。ここに私の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

これは、プロセスを通じて 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 レシーバー (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 に答える