Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm answering my own question, after the useful comments above, to show the solution I found and that seems to work. I'm not sure it's 100% correct (not tested what would happen with lines that are longer than the buffer).</p> <p>Differences with the first version:</p> <ul> <li>It extends <code>Reader</code>, not <code>BufferedReader</code>. It is simpler, and no need for a dummy reader. By making sure its children are <code>BufferedReader</code>, it can call <code>readLine()</code> on them.</li> <li>it still implements a <code>readLine()</code> which gives the functionality I was looking for</li> <li><code>read(char[], int, int)</code> is implemented using the <code>readLine()</code> above. That way, I'm sure lines are never broken. This is needed with, for example, <code>new LineNumberReader(new InterleavedReader(...)).readLine()</code>, which calls <code>read(char[], int, int)</code> on <code>InterleavedReader</code>.</li> </ul> <p>Here is the code. Please, let me know if you can suggest improvements!</p> <pre><code>public class InterleavedReader extends Reader { private int current = 0; private BufferedReader[] buffers = null; private boolean skipLF = false; public InterleavedReader(Reader[] in) { super(); buffers = new BufferedReader[in.length]; for (int i=0 ; i &lt; in.length ; i++) { if (in[i] instanceof BufferedReader) buffers[i] = (BufferedReader) in[i]; else buffers[i] = new BufferedReader(in[i]); } } public String readLine() throws IOException { // Every time, we issue readLine() to the next child BuffredReader // If we make a complete loop without a valid line, // then no child has more lines synchronized (lock) { int start = current; String line = null; while ((line = buffers[current].readLine()) == null) { current = (current+1) % buffers.length; if (current == start) return null; } current = (current+1) % buffers.length; return line; } } @Override public int read(char cbuf[], int off, int len) throws IOException { // To be sure we never break a line, we implement this using readLine() String s = readLine(); if (s == null) return -1; System.arraycopy(s.toCharArray(), 0, cbuf, off, s.length()); // readLine() doesn't include the '\n', append it to the buffer cbuf[off+s.length()] = '\n'; return s.length()+1; } private int readChar() throws IOException { int start = current; int c = -1; while ((c = buffers[current].read()) == -1) { current = (current+1) % buffers.length; if (current == start) return -1; } return c; } @Override public int read() throws IOException { synchronized (lock) { int c = readChar(); if (skipLF &amp;&amp; c == '\n') { c = readChar(); skipLF = false; } switch (c) { case '\r': skipLF = true; case '\n': /* Fall through */ current = (current+1) % buffers.length; return '\n'; } return c; } } @Override public boolean markSupported() { return false; } @Override public boolean ready() throws IOException { synchronized (lock) { for(int i=0; i &lt; buffers.length; i++) if (buffers[i].ready()) return true; return false; } } @Override public void close() throws IOException { synchronized (lock) { for (int i=0; i &lt; buffers.length; i++) buffers[i].close(); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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