我使用一个C#进程使用java命令运行以下java代码:
public class Test {
public static void main(String[] args) throws Exception {
Thread.sleep(2000);
System.out.print("Hello worl\nd 1!");
Thread.sleep(2000);
System.out.println("Hello world 2!");
}
}我使用以下代码来侦听输出:
run.OutputDataReceived += (_, args) => { /* handle output */ };
run.Start();
run.BeginOutputReadLine();理想情况下,OutputDataReceived应该被触发两次,其中args.Data的编码响应值为
"Hello worl\nd 1!""Hello world 2!\n"相反,换行符用于确定何时触发OutputDataReceived。这最终给出了对事件的3个调用,并给出了相应的args.Data值。
"Hello worl""d 1!Hello world 2!"null我将如何运行代码来根据我的第一个场景(每次stdout被更新)来处理输出,而不是当前正在发生的/第二个场景(每当stdout收到一个新行时)?此外,我如何对stderr也做同样的事情呢?
发布于 2022-07-31 17:17:44
对于其他有此问题的人,您可以使用this answer中描述的解决方案来获得实时输出。
发布于 2022-07-30 18:51:10
我认为你想要的是不可能的,这是故意的。
这些文本流不是由离散消息组成的,它是一个与TCP套接字非常相似的连续字节流。
如果您控制流的产生方和消耗方,则可以通过在该流之上实现一些框架协议来解决问题。这是一种简单的方法,它可能足够好使用双换行符的-separate消息。这样,您可以在C#端编写代码,读取缓冲区中积累的行,在找到或结束流引发事件时搜索双换行符,以处理完整的消息,除非流结束时将缓冲区的其余部分移动到缓冲区的开头。
另一个解决方法是使用其他一些IPC机制,而不是标准输出。在Windows上,命名管道支持PIPE_TYPE_MESSAGE标志,这将导致管道保留消息边界。类似地,Linux内核支持Unix域套接字的SOCK_DGRAM。在这两种情况下,常见的设计模式如下所示: 1.在父C#进程中生成唯一的管道/套接字名称,例如,生成一个新的GUID并打印该GUID。2.创建该名称的管道或插座。3.通过命令行参数或环境变量将该名称传递给子Java进程。4.在Java进程中,通过名称连接管道/套接字,然后在两个进程之间有一个面向消息的双向通信通道。
https://stackoverflow.com/questions/73178013
复制相似问题