Java并发控制台IO




我编写了带有消息功能的多线程Java Server-Client插座应用程序应用程序,但我遇到了同时的控制台io的问题。
Main Server控制台正在侦听键盘输入并同时从客户端打印消息。在客户端,有一个单独的打印线程。
这是简化的代码表示:

public class ServerThread{
....
BufferedReader in = ... (sock.getInputStream);
while(true){
  System.out.println(in.readline());
....
public class ServerMain{
.....
BufferedReader keyb = ... (System.in);
while(true){
  in = keyb.readLine();
....

当我在主服务器控制台中输入某些内容时,问题出现,同时邮件来自一个客户端。然后将该消息陈述为我在屏幕上输入的内容,并将光标移至下一行的开始等待输入。以前输入的内容被卡在键盘缓冲区中,我不能再编辑它了。同样的问题在客户端发生。

问题是如何在屏幕上打印消息而不破坏正在进行的输入?
(输入的文本还需要像readline((默认行为一样保留在屏幕上。

我已经尝试了针对其他类似问题的一些解决方案:
在Lanterna和Jcurses库中,对本机system.io流不支持。我必须重新发明轮子,然后手动地从内存到屏幕,一个char,一个char一次加上整个控制台GUI层。
另一件事是使用 ansi代码,但我不知道如何对它们做我需要的事情。我可以一次读取一个输入字符,而不是整个行,然后如果消息到达线,请将光标移至开始和打印输出,但是之后在Nextline中,我不知道如何以前如何打印缓冲文本,仍然能够使用Backspace

删除字符

编辑:
GUI不是一个选项,因为我希望我的代码能够在无头服务器上运行。
(还假设只有一个终端,控制台,shell和应用程序每次运行侧(

基于:只有一个控制台。

,该控制台是从多个线程不是真正问题的时代开始的人工制品。"与多个线程很好地使用"从来都不是该低级控制台的要求。

因此:如果您真的想要一个复杂的解决方案(这不是某种骇客(,请考虑:不使用stdin/stdout Console(S(。

而是:编写一个简单的摇摆GUI应用程序。有一个文本输入字段,其中收集了输入,一个或可能的多个文本字段在您的输出中。如果您想幻想,请将其变成WebApp。我确定使用一些框架,您可以在几个小时内将工作内容放在一起。这样做,您将学习更多的宝贵技能,而不是花这些时间"围绕"您为问题选择错误的技术这一事实。

更新,鉴于OP的评论:然后我能想到的最好的:不要写信给控制台。写入不同的文件。打开多个终端,并使用"尾巴"之类的工具向您展示输出文件正在发生的事情。

好吧,我自己找到了理想的解决方案:

jline 库与默认的system.io结合使用,也无需创建新的终端对象(您可以(或其他任何东西。简单而不是BufferedReader您使用 linereader

String readLine(String prompt, Character mask, String buffer)
  • prompt (可以为null(是未向前的提示模式,将显示给输入行左侧的用户

  • mask (也可以为null(是用于隐藏用户输入的字符(例如,在阅读密码时(

  • buffer是输入行的初始内容

编辑在Jline文档中,我找到了一个更好的解决方案:

prindabove

void prindabove(属性string str(

在提示之前打印一个字符串,并重新绘制所有内容。如果Linereader实际上没有读取一行,则字符串将只是 印刷到终端。

参数:
str-要打印的字符串*

最新更新