title: stdin not echoing on windows when read() called after available() checked (Interruptible readline implementation)
body: <p>I'm trying to implement an interruptible readline method [1] in Java , because the standard routine (using a buffered reader around System.in) isn't.  I've come up with a routine that works pretty well on Linux, but when you run it in Windows-land, the key-presses are not echoed to the console until the user presses enter - gah!</p>
  <p>After some experimenting, it seems the key-presses are only echo'd if there's a blocking call to <code>System.in.read()</code> while the user types.</p>
  <p>Does anyone know if this is fixable?  I tried to reflect my way in to using the private <code>java.ui.Console#echo</code> method, but it didn't seem to do anything.  My next port of call will be to have a look at the JNA API and see if I can get direct access to the console from there.</p>
  <p>1 - For reference, here's my interruptible readline implementation.  I capture ctrl-c and interrupt the thread that's calling readline - handled elsewhere, working, and probably not relevant for this example</p>
  <pre class="lang-java prettyprint-override"><code>import java.io.EOFException;
  import java.io.IOException;
  import java.io.InputStream;
  
  public class EchoTest {
  
    private static final long MILLIS_BETWEEN_STDIN_CHECKS = 10;
  
    public static void main(String[] args) throws IOException, InterruptedException {
      System.out.println(&quot;Type something&quot;);
      // on windows, there's no echo until enter, dammit!
      String input = readline(System.in);
      System.out.println(&quot;Hello, &quot; + input);
    }
  
  
    /**
     * Read a line of input from an input stream, presumably stdin.
     *
     * @param stdin An InputStream to read a line from. 
     *
     * @return the string that was read, with the line terminator removed.
     *
     * @throws IOException if there was an io error reading from stdin
     * @throws InterruptedException if the thread was interrupted while waiting to receive keypresses
     */
    public static String readline(InputStream stdin) throws IOException, InterruptedException {
  
      // we use mark to peek ahead for \r\n
      if (!stdin.markSupported()) {
        throw new IllegalArgumentException(&quot;stdin must support mark&quot;);
      }
  
      // result is stored in here
      StringBuffer stringBuffer = new StringBuffer(512);
      // a byte buffer as we read a byte at a time from stdin
      byte[] bytes = new byte[64];
      // number of bytes we've read in to the buffer
      int bytesRead = 0;
  
      while (true) {
  
        // check whether read should block
        if (stdin.available() &gt; 0) {
  
          int byteRead = stdin.read();
  
          if (byteRead == -1) {
            // end of stream - not expected for readline
            throw new EOFException();
          }
  
          // check for line ending character sequences, we need to detect \r, \n or \r\n
          if (byteRead == '\n') {
            // we're done!
            break;
          } else if (byteRead == '\r') {
            // we're done, but we might need to consume a trailing \n
            if (stdin.available() == 0) {
              // nothing is ready, we presume that if \r\n was sent, then they'd be sent as one and the buffer would
              // already have the \n
              // worst case, the next call to readline will exit with an empty string - if this appears to happen, we
              // could detect a \n being in stdin at the start and drop it on the floor
              break;
            } else {
              // there is a byte there - mark our position and check if it's \n
              stdin.mark(1);
              if (stdin.read() == '\n') {
                // it is we're done
                break;
              } else {
                // it isn't \n, reset position for the next call to readline or read
                stdin.reset();
                break;
              }
            }
          } else {
            bytes[bytesRead++] = (byte)byteRead;
  
            // flush buffer if it's full
            if (bytesRead == bytes.length) {
              stringBuffer.append(new String(bytes, 0, bytesRead));
              bytesRead = 0;
            }
  
          }
  
        } else {
          if (Thread.interrupted()) {
            throw new InterruptedException();
          } else {
            Thread.sleep(MILLIS_BETWEEN_STDIN_CHECKS);
          }
        }
  
      }
  
      stringBuffer.append(new String(bytes, 0, bytesRead));
  
      return stringBuffer.toString();
    }
  
  
  }
  
  </code></pre>