title: Why doesn't Files.newInputStream(path) support the available method on FIFOs?
body: <p>Take this simple test class:</p>
  
  <pre><code>public class InputStreamTest {
  
      public static void main(String[] args) throws IOException {
          byte[] buf = new byte[100];
          Path path = Paths.get(args[0]);
          System.out.println("File " + path);
  
          try (InputStream is = new BufferedInputStream(new FileInputStream(path.toFile()))) {
  //      try (InputStream is = new BufferedInputStream(Files.newInputStream(path))) {
              System.out.println("Available: " + is.available());
              System.out.print("First 100 bytes: '");
              is.read(buf);
              System.out.write(buf);
              System.out.println("'");
          }
      }
  }
  </code></pre>
  
  <p>This takes a filename/path on the command line and simply prints out the result of <code>available()</code> on the corresponding <code>InputStream</code> and up to<sup>1</sup> the first 100 bytes from the stream.</p>
  
  <p>It works fine, even when you pass it redirected command output (which internally will create a FIFO and pass it as the file argument). For example, running it as:</p>
  
  <pre><code>java InputStreamTest &lt;(echo -n "ABC")
  </code></pre>
  
  <p>... results in the following output:</p>
  
  <pre><code>File /dev/fd/63:
  Available: 3
  First 100 bytes: 'ABC'
  </code></pre>
  
  <p>Looks good so far. Now, uncomment the line that uses the new-and-recommended-Java-7-ish <code>Files.newInputStream(path)</code> to create the <code>InputStream</code> and comment our the prior line which uses the oldschool <code>FileInputStream</code> class. Now it fails:</p>
  
  <pre><code>File /dev/fd/63
  Exception in thread "main" java.io.IOException: Illegal seek
      at sun.nio.ch.FileChannelImpl.position0(Native Method)
      at sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:264)
      at sun.nio.ch.ChannelInputStream.available(ChannelInputStream.java:116)
      at java.io.BufferedInputStream.available(BufferedInputStream.java:410)
      at net.tdowns.compression.InputStreamTest.main(InputStreamTest.java:20)
  </code></pre>
  
  <p>Evidently the <code>available()</code> method on the stream is failing. Now you might just say "hey, don't call <code>available()</code> it is pretty much useless". Unfortunately, a class as core as <code>BufferedInputStream</code> uses it! If you comment out the direct call to <code>available()</code>, this <em>still</em> fails:</p>
  
  <pre><code>File /dev/fd/63
  First 100 bytes: 'Exception in thread "main" java.io.IOException: Illegal seek
      at sun.nio.ch.FileChannelImpl.position0(Native Method)
      at sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:264)
      at sun.nio.ch.ChannelInputStream.available(ChannelInputStream.java:116)
      at java.io.BufferedInputStream.read(BufferedInputStream.java:353)
      at java.io.FilterInputStream.read(FilterInputStream.java:107)
      at net.tdowns.compression.InputStreamTest.main(InputStreamTest.java:22)
  </code></pre>
  
  <p>So you are in a pretty tough spot - if you use <code>Files.newInputStream(path)</code>, the <code>available()</code> call might fail, and you can't really avoid use of this call since other JDK stream classes themselves like to call it.</p>
  
  <p>Any way out?</p>
  
  <hr>
  
  <p><sup>1</sup> I say <em>up to</em> because of course the <code>read()</code> method may return fewer than the requested number of bytes, even if more are available. In practice, it doesn't do that for files and for fifos you get at least a few K, so this will <em>usually</em> print out 100 bytes if 100 bytes are available.</p>