gpt4 book ai didi

java - System.in 和自定义 InputStreamReader 之间的行为差​​异

转载 作者:行者123 更新时间:2023-11-30 09:29:08 25 4
gpt4 key购买 nike

我编写了一个 Java CLI 程序,它从 stdin 读取行并为每一行输出可能的完成。我正在尝试给它一个图形用户界面,所以我正在尝试为 System.in 构建一个直接替代品,以允许用户使用图形用户界面或命令行界面。

到目前为止,我得到了这个替换,当在 JTextArea 中输入文本时调用其方法 add:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class GuiIn extends InputStream {

protected LinkedBlockingQueue<Byte> buf;
protected boolean closed;

public GuiIn() {
closed = false;
buf = new LinkedBlockingQueue<Byte>();
}

@Override
public void close() {
closed = true;
}

/**
* add strings to read in the InputStream. Arguments are ignored if the
* stream is closed.
*
* @param s
* a string. Ignored if null
*/
public void add(String s) {
if (closed || s == null) {
return;
}
byte[] bs = s.getBytes();
LinkedList<Byte> lbs = new LinkedList<Byte>();
for (byte b : bs) {
lbs.add(b);
}
buf.addAll(lbs);
}

@Override
public int available() {
return buf.size();
}

@Override
public synchronized int read() throws InterruptedIOException {
if (closed && buf.isEmpty()) {
return -1;
}
Byte b = 0;

while (true) {
try {

if ((b = buf.poll(100, TimeUnit.MILLISECONDS)) == null) {
if (closed && buf.isEmpty())
return -1;
} else
break;

} catch (InterruptedException e) {
throw new InterruptedIOException("interrupted: "
+ e.getMessage());
}
}
return b;
}
}

但是,当我尝试使用 new BufferedReader(new InputStreamReader(in)); 并尝试 readLine() 时,它似乎会阻塞直到它有足够的字符(很多),尽管我的听众总是在输入的文本后面附加一个换行符。

另一方面,如果 in 设置为 System.in,则每行在输入时立即读取。

所以,我的问题分为两部分:

  1. 这种差异从何而来?
  2. 如何解决?

请注意,从光秃秃的 GuiIn 逐字节读取工作正常,而且我已经尝试过一些技巧,例如减小 BufferedReader 缓冲区的大小。

我也事先在网上搜索过:这不是关于创建模拟对象;和 ByteArrayInputStream也不是一个选项:它不支持附加。

最佳答案

您的问题的一个来源可能是 InputStreamReader 可能坚持读取更远的前方,以便它可以确定 byte->char它使用的解码器(对它来说是不透明的)有足够的字节来生成完整的 charSystem.in 可能对默认编码有足够的了解以提供足够的字节。

在开始使用 Java 进行交互式控制台操作之前,您应该熟悉 Console类和 readline to Java端口。

然后,我不会在不指定编码的情况下创建 InputStreamReader,而是在更高层次上进行抽象:

interface CommandLineSource {
String readLine() throws IOException;
}

然后您可以创建一个由 FileDescriptor.STDIN 支持的,另一个由您喜欢的任何内容支持,以便您可以自动输入以进行测试。

关于java - System.in 和自定义 InputStreamReader 之间的行为差​​异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13730553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com