Search code examples
javastdinfile-descriptorfileinputstreamfileoutputstream

Unexpected behaviour of FileInputStream & FileOutputStream classes, when used with in and out static members of FileDescriptor in JAVA


In the source code of FileDescriptor.java we have following static variables:

  /**
  * A handle to the standard input stream. Usually, this file
  * descriptor is not used directly, but rather via the input stream
  * known as <code>System.in</code>.
  *
  * @see java.lang.System#in
  */
  public static final FileDescriptor in = new FileDescriptor(0);

  /**
  * A handle to the standard output stream. Usually, this file
  * descriptor is not used directly, but rather via the output stream
  * known as <code>System.out</code>.
  * @see java.lang.System#out
  */
  public static final FileDescriptor out = new FileDescriptor(1);

Here I am using it directly, not as System.out. Now check the following program:

import java.io.*;
public class First
{
    public static void main(String[] args) throws Exception
    {
       FileInputStream fis = new FileInputStream(FileDescriptor.out);
       byte[] b = new byte[8];
       System.out.println(fis.read(b));//6
       for(byte b1: b)
       {
          System.out.println(b1);
       }
    }
}

Input

hello

Output

  6
  104
  101
  108
  108
  111
  10
  0
  0

Notice that, even if I am using FileDescriptor.out in the constructor, it is not giving any error and working perfectly for the standard input stream.

Check one more program:

import java.io.*;
public class First
{
    public static void main(String[] args) throws Exception
    {
        FileOutputStream fos = new FileOutputStream(FileDescriptor.in);
        byte[] b = {65, 66, 67};
        fos.write(b);
    }
}

Output

ABC

Notice that, even if I am using FileDescriptor.in in the constructor, it is not giving any error and working perfectly for the standard output stream.

I know FileDescriptor in java is opaque, and I should not compare it with the file-descriptor concept in Linux. I just want to know how it is created in JAVA. And if one static variable can do both reading and writing, then what is the need of three (in, out and err).


Solution

  • If you're running your test from a shell, without redirections, then file descriptors 0, 1 and 2 are probably the same file : /dev/tty or something like that (your terminal).

    That would explain why you can read/write from any of those descriptors.