如何使用 BufferedReader 和 BufferedWriter 通过 processBuilder 与进程的控制台进行交互

问题描述 投票:0回答:1

我已经构建了一个基于文本的二十一点游戏,并且正在编写一个机器人来玩游戏并记录结果。我已成功启动游戏并从控制台读取初始数据,但是一旦机器人决定其移动,我就无法将其写入 Blackjack 控制台或检索游戏提供的响应。

这是到目前为止的代码:

public static void main(String[] args) {
        try {
            ProcessBuilder builder = new ProcessBuilder("java","app.App");
            builder.directory(new File("C:\\Users\\damon\\OneDrive\\school\\code\\BlackJack"));
            builder.redirectErrorStream(true);
            Process process = builder.start();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
                    String line1 = reader.readLine(); // Player's total
                    String line2 = reader.readLine(); // Player's cards
                    String line3 = reader.readLine(); // Can split
                    String line4 = reader.readLine(); // Dealer's total
                    String line5 = reader.readLine(); // Dealer's cards
                    // Process the lines to extract and store the data
                    int playersTotal = Integer.parseInt(line1);
                    String[] playerCards = line2.split(" ");
                    boolean canSplit = line3.equals("s");
                    int dealersTotal = Integer.parseInt(line4);
                    String[] dealerCards = line5.split(" ");
                    Stratergy strat=new Stratergy(playersTotal, playerCards[0], canSplit,dealersTotal);
                    writer.write(strat.suggestAction()+"\n");
                    System.out.println(line1+"\n"+line2+"\n"+line3+"\n"+line4+"\n"+line5+"\n"+strat.suggestAction());
                    System.out.println(reader.readLine());          
            reader.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
java processbuilder bufferedwriter blackjack
1个回答
0
投票

正如“缓冲区”一词所暗示的那样,

BufferedWriter
缓冲区

这意味着

someBufferedWriter.write("Hello!")
根本不做任何事情。它只是......推“你好!”在缓冲区中。这纯粹是一个内存操作。底层流没有发生任何事情。

这就是要点 - 许多原始操作系统级资源具有与它们交互成本高昂的属性,并且往往不像连续的数据流那样工作,而是作为一系列块重新构成另一边川流不息。显而易见的结论是,与仅发送完整块的数据相比,一次发送 1 个字节是难以置信的低效(例如,慢数千倍)。

这就是它以这种方式工作的原因 -

如果你需要缓冲的东西,就使用它。如果你不这样做,那就不要。或者,如果您以某种方式坚持在这里使用 BufferedWriter

,则 
flush()
 调用会告诉 BW 
now 发送其缓冲区。所以,补充一下。在您拨打 .write
 电话后,立即拨打 
flush()
。直到你这样做(或者直到 BW 对象决定其缓冲区已满,足以触发一个块,而这个小命令字符串肯定不会填满),你正在启动的 java 进程不会收到任何数据。

请注意,除了 PB,您还可以重新分配 sysin 和 sysout (

System.setIn

 / 
System.setOut
),然后自己调用 
app.App.main(args)
。保存 JVM 调用,并且可能比在这里使用 ProcessBuilder 简单得多。但是,一旦添加了flush(),事情就会正常进行。或者,如果仍然没有,则两个进程之间的通信通道不再是问题。

© www.soinside.com 2019 - 2024. All rights reserved.