Java - 如何终止非阻塞stdin读取循环

时间:2016-12-15 13:12:29

标签: 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”终止。任何想法,谢谢。

2 个答案:

答案 0 :(得分:1)

基于Read Input until control+d

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

如果您看到Aleadam回复,您可以看到如何检查CTRL + D:

extern S tool; // declare tool

如果您看到此Convert a byte array to integer in java and vice versa

和Jeff Mercado回复你可以做到以下几点:

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());
  }
}

答案 1 :(得分:0)

尝试使用此代码。它对我有用:

try {
    while ((bytesAvailable = System.in.read(buffer)) != -1) {
        myOutputStream.write(buffer, 0, bytesAvailable);
        myOutputStream.flush();
} catch (IOException e) {}

CTRL-D将使终端使缓冲输入可用。如果它自己的行没有任何内容,CTRL + D会向System.in输入流发送一个EOF信号,该信号为-1。