Path: csiph.com!usenet.pasdenom.info!news.albasani.net!.POSTED!not-for-mail From: Jan Burse Newsgroups: comp.lang.java.programmer Subject: Re: Making System.in interruptible, how? Date: Fri, 09 Mar 2012 01:17:50 +0100 Organization: albasani.net Lines: 118 Message-ID: References: <4f499da4$0$290$14726298@news.sunsite.dk> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 8bit X-Trace: news.albasani.net r/Kle/Yj+Go1BPZp4u8SYy0zljtfZ7zJGHuA0AZgDm+zRinCSwz0OYjUoZYhZ0egVVOtw56Jdh/Q3LoXrFpTPwc6AE8CNYTGNm+PJNzo4djRBvluBrK6qsHdSoR83tr3 NNTP-Posting-Date: Fri, 9 Mar 2012 00:17:51 +0000 (UTC) Injection-Info: news.albasani.net; logging-data="RhOKO/B7lGtMdQYy9LhUJirWWIPL92Reb1Ml+vRIXBiWZeVb4gZ135ap1GPZHP/7q2BlPBjN3efZTSRqRCx0gIm12CnXHTFQTEc3JZwal63i3p6PKkP6xIc54k5RUDsI"; mail-complaints-to="abuse@albasani.net" User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Firefox/10.0.2 SeaMonkey/2.7.2 In-Reply-To: <4f499da4$0$290$14726298@news.sunsite.dk> Cancel-Lock: sha1:ohE8hBi+/PGE2RjdHNDY6yPWQWI= Xref: csiph.com comp.lang.java.programmer:12783 Arne Vajhøj schrieb: > 2) BufferedReader ready will only return true if a full line > is available and not eat any characters if that is not the case I guess that is more a freature of the underlying console, if echo is off and the console is in line editing mode. For example I can do the following: abcdef And I will get from BufferedReader abdef and not abcdef. But there is no logic in BufferedReader for line editing. There is only some skip LF logic in the buffered reader. Also the buffered reader will delegate the ready() to the underlying stream. > The core logic in the code is: > > while (!br.ready()) { > Thread.sleep(200); > } Yep, but I have a bad feeling concerning the above logic. What if the input of the console is redirected, and some file should be processed. Then the sleep will throttle the input considerable. Best would be if the stream underlying BufferedReader would be interruptible. That is if System.in or a substitute would be interruptible. > I would seriously consider writing some JNI to do > what is necessary on the relevant platforms. > > It is not portable, but at least it is obvious how it works. Or maybe some sun.misc.* stuff. Which is a little bit more widespread, and can be used via reflection, so that when sun.misc.* is present interruptibility could be provided, and otherwise the stream would not be interruptible as before. Unfortunately the following does also not yield an interruptible console stream: Console console = System.console(); Reader reader = console.reader(); The reader there is created as follows: reader = new LineReader(StreamDecoder.forInputStreamReader( new FileInputStream(FileDescriptor.in), readLock, cs)); So maybe something can be done with FileDescriptor.in? There is a hack documented here: Here is a way to get a NIO FileChannel from System.in http://stackoverflow.com/a/808795/502187 /* unravels all layers of FilterInputStream wrappers to get to the * core InputStream */ public static InputStream extract(InputStream in) throws NoSuchFieldException, IllegalAccessException { Field f = FilterInputStream.class.getDeclaredField("in"); f.setAccessible(true); while( in instanceof FilterInputStream ) in = (InputStream)f.get((FilterInputStream)in); return in; } Maybe I can get the channel without reflection from the file descriptor? Actually this is possible: FileInputStream fi = new FileInputStream(FileDescriptor.in); final Thread thread = Thread.currentThread(); new Thread() { public void run() { try { Thread.sleep(2000); } catch (InterruptedException x) { throw new RuntimeException(x); } thread.interrupt(); } }.start(); System.out.print("test: "); System.out.flush(); ByteBuffer buf = ByteBuffer.allocate(1024); try { fi.getChannel().read(buf); } catch (IOException x) { throw new RuntimeException(x); } If run it I get: test: ... Caused by: java.nio.channels.ClosedByInterruptException at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202) at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:148) ... 5 more Bye