Java 无法可靠地写入控制台应用程序

Java 无法可靠地写入控制台应用程序,java,processbuilder,linphone,Java,Processbuilder,Linphone,我正在调用linphonec.exe,这是一个用于控制Linphone的交互式控制台应用程序,它是一个通过Windows 7上的Java(1.8u11)实现的类似Skype的开源应用程序 在Linphone 3.8.2中,一切都运行得很好,但是在更新到3.9.1之后,我无法再可靠地将Java中的命令调用到应用程序中,有些命令被处理,有些命令被默默地忽略 要重新创建的小示例,发出help命令 public class CommandTest { private static class C

我正在调用linphonec.exe,这是一个用于控制Linphone的交互式控制台应用程序,它是一个通过Windows 7上的Java(1.8u11)实现的类似Skype的开源应用程序

在Linphone 3.8.2中,一切都运行得很好,但是在更新到3.9.1之后,我无法再可靠地将Java中的命令调用到应用程序中,有些命令被处理,有些命令被默默地忽略

要重新创建的小示例,发出help命令

public class CommandTest {
    private static class Consumer implements Runnable {
        private InputStream stream;
        public Consumer(InputStream stream) {
            this.stream = stream;
        }
        @Override
        public void run() {
            int c = 0;
            try {
                while ((c = stream.read()) != -1) {
                    System.out.print((char) c);
                }
                System.out.println("Stream finish");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ProcessBuilder builder = new ProcessBuilder(
                Arrays.asList("C:\\Program Files (x86)\\Linphone\\bin\\linphonec.exe"));
        builder.redirectInput(Redirect.PIPE);
        Process process = builder.start();
        new Thread(new Consumer(process.getInputStream())).start();
        new Thread(new Consumer(process.getErrorStream())).start();
        BufferedWriter stdin = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), StandardCharsets.US_ASCII));
        stdin.write("help\n");
        stdin.flush();
        process.waitFor();
    }
}
输出-带3.8.2

Ready
Warning: video is disabled in linphonec, use -V or -C or -D to enable.
linphonec> Commands are:
---------------------------
      help  Print commands help.
      call  Call a SIP uri or number
      ... etc... 
输出-带3.9.1

Ready
linphonec> linphonec> 
分析
  • 问题缩小到linphonec.exe的输出,它似乎对命令做出了响应,但这些命令并没有被迅速刷新到其标准输出

  • 例如,下面的方法确实有效,但只有在运行了许多帮助命令后才能得到结果,我只能假设这意味着子进程的输出缓冲区已达到某个级别,在这种情况下,刷新会自动发生

代码

输出

linphonec> linphonec> linphonec> linphonec> linphonec> linphonec> linphonec> linphonec> Warning: video is disabled in linphonec, use -V or -C or -D to enable.
0: StaticImage: Static picture
0: StaticImage: Static picture
0: StaticImage: Static picture
0: StaticImage: Static picture
Commands are:
---------------------------
      help  Print commands help.
    answer  Answer a call
autoanswer  Show/set auto-answer mode
      call  Call a SIP uri or number
  • 这一结论得到了以下事实的支持:“警告:视频在linphonec中被禁用,请使用-V或-C或-D来启用。”这一行仅在稍后打印,即使它是在主循环启动之前写入main init()方法的。该行在3.8.2中立即出现,但仅在3.9.1中刷新标准输出缓冲区后出现
linphone信号源分析

大多数输出,如帮助等,都在linphonec.c中使用linphonec_out,这有一个显式的fflush(),但似乎不起作用

char *res;
va_list args;
va_start (args, fmt);
res=ortp_strdup_vprintf(fmt,args);
va_end (args);
printf("%s",res);
fflush(stdout);
问题

  • 为什么冲洗会在3.8.2中立即发生,而不是在3.9.1中
  • 我在Java中是否有明显的错误
  • 任何人都可以使用这种方法和Linphone Desktop的最新版本成功地与Java集成
也许您可以检查哪个版本提供了回归,然后检查其发行说明(甚至提交)。您可以测试一些3.8.x版本。也许您可以检查哪个版本提供了回归,然后检查其发行说明(甚至提交)。您可以测试一些3.8.x版本。
char *res;
va_list args;
va_start (args, fmt);
res=ortp_strdup_vprintf(fmt,args);
va_end (args);
printf("%s",res);
fflush(stdout);