FileInputStream 和 FileOutputStream 的意外行为 类,与 JAVA 中文件描述符的 in 和 out 静态成员一起使用时

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

在 FileDescriptor.java 的源代码中,我们有以下静态变量:

  /**
  * 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);

这里我是直接用的,不像System.out。现在检查以下程序:

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);
       }
    }
}

输入

hello

输出

  6
  104
  101
  108
  108
  111
  10
  0
  0

请注意,即使我在构造函数中使用 FileDescriptor.out,它也不会给出任何错误并且可以完美地用于标准输入流。

再检查一个程序:

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);
    }
}

输出

ABC

请注意,即使我在构造函数中使用 FileDescriptor.in,它也不会给出任何错误并且可以完美地用于标准输出流。

我知道 java 中的 FileDescriptor 是不透明的,我不应该将它与 Linux 中的文件描述符概念进行比较。我只想知道它是如何在 JAVA 中创建的。如果一个静态变量既可以读又可以写,那还需要三个(in,out,err)。

如果您 运行 您的测试来自 shell,没有重定向,那么文件描述符 0、1 和 2 可能是同一个文件:/dev/tty 或类似的文件(您的终端机)。

这可以解释为什么您可以 read/write 来自任何这些描述符。