当前位置: 首页 > 面试题库 >

Java:除非手动刷新,否则无法从Process获取stdout数据

鱼安然
2023-03-14
问题内容

我正在用Java编写命令行程序的终端包装,然后使用ProcessBuilder生成子进程。将击键发送到子,我只是写e.getKeyChar()从GUI直奔OutputStream
给出proc.getOutputStream()。为了从子流程接收输出,我基本上有一个while循环,它从子流程的中读取stdout

while ((b = br.read()) != -1) {
    System.out.println("Read "+b);
    bb[0] = (byte) b;
    // call an event listener with the read byte
    listener.dataReceived(bb);
}

这工作, 只有 当我立刻冲在输出
结束。也就是说,我必须刷新每个用户输入,并且子进程必须刷新自己的stdout输入才能发生操作。否则,将read()等待从未真正发送的等待数据的块(子进程的stdout仅保持缓冲)。如何使I
/ O正常运行?

终端子流程示例:

#include <stdio.h>

int main() {
    char c;
    while((c = getchar()) != -1) {
        printf("Got: %d\n", c);
        // doesn't work in my Java program if the next line isn't present
        fflush(stdout);
    }
    return 0;
}

我正在使用Sun Java 6在Ubuntu 10.10上运行。


问题答案:

许多运行时库(例如,我知道libc会这样做,如果其他人也这样做,也不会感到惊讶)默认情况下会缓冲其输出, 除非
输出到终端。当处理许多行时(例如,在正常管道中),这极大地提高了数据处理的效率,但是当信息量很少时,它会带来很多伤害。如果您有权访问子流程的源,那么绝对最好通过关闭缓冲或添加刷新来更新代码。

但这并不总是可能的,尤其是在处理第三方代码时。在这种情况下,我所知道的最佳 其他
修复方法是使用Expect等工具欺骗子流程。在内部,Expect知道如何伪装成终端(在Unix上使用pty和在Windows上使用令人讨厌的黑客手段),从而欺骗其他程序以关闭(或至少减少)它们的缓冲。对于Expect,有一个脚本-
unbuffer-使它专门针对这种使用。(通常,它不仅可以处理不规则的缓冲,还可以做很多事情,但这还是最好的解决方法。)



 类似资料:
  • 我目前正在使用JQuery mobile开发一个移动网站。我在我的foobar中使用了多个页面。html导航,如下所示: 我加载foobar。html文件,单击Go to Bar,即可正常工作;然而,当我从索引导航时。hmtl到foobar。html并再次测试,链接无法工作。刷新页面可以解决此问题。 如何解释这种行为以及如何修复它?

  • 我的应用程序使用Spring 4.3. x、EhCache 3.6和javax Cache 1.1.0。以下是我在应用程序中配置javax CacheManager的方式: AppCacheManagerFactoryBean(只是JCacheManagerFactoryBean的自定义版本)帮助我为我的应用程序配置全局持久性目录。这是它的外观: 这是我如何定义缓存的。我使用Ehcache API

  • > 我无法刷新旋转项选择上的列表视图。 我希望基于spinner的items值构建新的url,以获取新的json数据并转换为ListView。 您还可以帮助我说明如何创建一个方法来传递新url以获取新数据。 主要问题与标题相同,您的每一个帮助都将不胜感激。

  • 问题内容: 这是我的配置: 根据此处找到的logback文档(http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy),文件将根据我的fileNamePattern 每分钟翻转一次。 我观察了它是如何工作的,这是我的发现: 它不会在很短的时间内创建日志文件。 当新日志到达时,它只会为前一分钟创建一个日志文件。(例如,我在

  • 我有一个Jfreechart,它正在绘制一些模拟实时数据。当我将域轴设置为自动时,可以看到数据每秒更新一次。然而,我希望在更大范围内(比如说一整天)绘制数据。当我更改范围时,除非放大,否则无法看到绘图。 如何使其连续(显示序列中的每个观测点),以及如何在手动设置范围时使其可见

  • 我一直在尝试使用nativescript创建一个android应用程序。我正在使用fetch模块从服务器获取响应。当我试图从httpbin获得响应时。org/get,没关系。但当我试图从本地服务器获取响应时,网络请求失败。错误 发送到httpbin。组织/获取- 发送到本地主机:8000/api- 当我尝试从纯节点中的localhost:8000/api获取响应时。js通过请求模块。它工作得很好。