Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>One way to do it would be as follows:</p> <ul> <li>create a subclass of OutputStream that redirects its output to a Pipe's sink channel</li> <li>redirect System.out using this class: <code>System.setOut(new PrintStream(new MyOutputStream(pipe));</code></li> <li>register the pipe's source channel with a selector and get whatever was written to System.out in the selector loop, i.e. the source channel's correpsonding SelectionKey is selected as readable()</li> </ul> <p>The following immplementation is a naive but working implementation, which simply redirects to System.err everything that is written to System.out:</p> <pre><code>import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; public class SystemOutPipe extends Thread { public static void main(String[] args) { try { SystemOutPipe sop = new SystemOutPipe(); sop.start(); System.out.println("This message should be redirected to System.err\nNow waiting 5 seconds ..."); Thread.sleep(5000L); sop.setStopped(true); sop.join(); } catch (Exception e) { e.printStackTrace(); } } private Selector selector; private Pipe pipe; private boolean stopped = false; public SystemOutPipe() throws IOException { super("SystemOutPipe"); pipe = Pipe.open(); System.setOut(new PrintStream(new PipeOutputStream(pipe))); selector = Selector.open(); pipe.source().configureBlocking(false); pipe.source().register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } @Override public void run() { try { while (!isStopped()) { int n = selector.select(1L); if (n &gt; 0) { Iterator&lt;SelectionKey&gt; it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); it.remove(); if (key.isReadable()) { new ReadHandler(key).run(); } } } } } catch (Exception e) { e.printStackTrace(); // writes to System.err ! } } public synchronized boolean isStopped() { return stopped; } public synchronized void setStopped(final boolean stopped) { this.stopped = stopped; } public class ReadHandler implements Runnable { private final SelectionKey key; public ReadHandler(final SelectionKey key) { this.key = key; } @Override public void run() { ByteBuffer bbuf = (ByteBuffer) key.attachment(); ReadableByteChannel channel = (ReadableByteChannel) key.channel(); try { int count = 0; do { bbuf.clear(); count = channel.read(bbuf); if (count &gt; 0) System.err.write(bbuf.array(), 0, count); } while(count &gt; 0); } catch (IOException e) { e.printStackTrace(); key.cancel(); } } } public class PipeOutputStream extends OutputStream { private final Pipe pipe; public PipeOutputStream(final Pipe pipe) { this.pipe = pipe; } @Override public void write(final int b) throws IOException { write(new byte[] { (byte) b }); } @Override public void write(final byte[] b) throws IOException { write(b, 0, b.length); } @Override public void write(final byte[] b, final int off, final int len) throws IOException { ByteBuffer bbuf = ByteBuffer.wrap(b, off, len); bbuf.position(len); bbuf.flip(); int count = 0; while (count &lt; len) { int n = pipe.sink().write(bbuf); if (n == 0) { // let's wait a bit and not consume cpu try { Thread.sleep(1L); } catch (InterruptedException e) { throw new IOException(e); } } else count += n; } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload