Java - 如何终止非阻塞标准输入读取循环

标签 java io

这是我的 Java 程序中的一段代码(在主线程中):

int bufSize = 4096; // 4k buffer.
byte[] buffer = new byte[bufSize]; 
int bytesAvailable, bytesRead;
try {
    while ( true ) {
        bytesAvailable = System.in.available(); // seems may throw IOException if InputStream is closed.
        if ( bytesAvailable > 0 ) {
            if ( bytesAvailable > bufSize ) {
                bytesAvailable = bufSize;
            }
            // The following statement seems should not block. 
            bytesRead = System.in.read(buffer, 0, bytesAvailable);
            if ( bytesRead == -1 ) {
                myOutputStream.close();
                System.out.println("NonBlockingReadTest : return by EOF.");
                return;
            }
            myOutputStream.write(buffer, 0, bytesRead);
            myOutputStream.flush();
        } else if ( bytesAvailable == 0 ) {
            // Nothing to do, just loop over.
        } else { 
            // Error ! Should not be here !
        }
    }
} catch (IOException e) {
.....

程序运行正常。它只是从 stdin 读取(以非阻塞方式)一些输入,然后将输入写入文件。我使用了“System.in.available()”,这样“System.in.read(buffer, 0, bytesAvailable)”语句就不会阻塞。

但是,我无法通过在键盘中键入“ctrl-D”来终止程序。我只能通过“ctrl-C”来终止它,我认为这不是一个优雅的方式。看来“bytesRead == -1”条件永远不会成立。

我可以做任何修改,以便可以通过“ctrl-D”终止程序吗?任何想法,谢谢。

最佳答案

基于Read Input until control+d

您可以使用 ByteBuffer 从缓冲区读取整数。 然后您可以将该 int 与 4 进行比较。如果是,则它是 CTRL+D。

如果您看到 Aleadam 响应,您可以了解如何检查 CTRL+D:

public class InputTest {
  public static void main(String[] args) throws IOException {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    StringBuilder out = new StringBuilder();
    while (true) {
      try {
        int c = in.read();
        if (c != 4)  // ASCII 4 04 EOT (end of transmission) ctrl D, I may be wrong here
            out.append (c);
        else
            break;
      } catch (IOException e) {
        System.err.println ("Error reading input");
      }
    }
    System.out.println(out.toString());
  }
}

如果你看到这个Convert a byte array to integer in java and vice versa

杰夫·梅尔卡多 (Jeff Mercado) 回应您可以执行以下操作:

byte[] arr = { 0x00, 0x01 };
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default
short num = wrapped.getShort(); // 1

ByteBuffer dbuf = ByteBuffer.allocate(2);
dbuf.putShort(num);
byte[] bytes = dbuf.array(); // { 0, 1 }

关于Java - 如何终止非阻塞标准输入读取循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41165058/

相关文章:

java - Spring 启动: Consume Secured API with Basic Authentication

java - JPA 在使用 selectcase 构造查询时处理空值

io - Win7 上的秃鹰 : connection issue (Errno 10054)

c# - 为什么函数输出错误的值?

c++ - 如何在文本文件中搜索单词,如果找到则打印出整行

更改顺序修复了我的错误。为什么?

java - 在 Tomcat 中禁用 SSL/TLS 重新协商

java - 输入流和输入流读取器

java.lang.NoSuchMethodException : scala. collection.immutable.$冒号$冒号

java - 创建最近删除的文件时出现 AccessDeniedException