该类无继承关系,引入了如下包:
import java.util.ArrayList; import java.util.List;
该类属于final类,其类头注释如下:
/** * Instances of the file descriptor class serve as an opaque handle * to the underlying machine-specific structure representing an open * file, an open socket, or another source or sink of bytes. The * main practical use for a file descriptor is to create a * <code>FileInputStream</code> or <code>FileOutputStream</code> to * contain it. * <p> * Applications should not create their own file descriptors. * * @author Pavani Diwanji * @see java.io.FileInputStream * @see java.io.FileOutputStream * @since JDK1.0 */
大意如下:
该类的实例是作为与底层机器结构相关的不透明句柄
可以表示开放文件,开放套接字,另一个源或者部分沉底字节
该类最主要的实用方法就是去创建一个包含该类的FIleInputStream或者FileOutputStream
应用程序不应该创建自己的文件描述符类
该类含有如下的成员变量:
int类的文件描述符:
private int fd;
直接父文件路径:(Closeable方便描述,因为具体对象类可能不同
private Closeable parent;
其他间接父文件路径:
private List<Closeable> otherParents;
标志状态位(当前流是否关闭)
private boolean closed;
该类含有如下的方法:
公共构造函数(默认)
public /**/ FileDescriptor() { fd = -1;//-1为无效 }
私有构造函数(根据成员方法的判定进行赋值)
private /* */ FileDescriptor(int fd) { this.fd = fd; }
文件输入流句柄in(标准
public static final FileDescriptor in = new FileDescriptor(0);//0为输入流标示
文件输出流句柄out(标准
public static final FileDescriptor out = new FileDescriptor(1);//1为输出流标示
错误流句柄err(标准
public static final FileDescriptor err = new FileDescriptor(2);//2为错误流标示
判定文件标识符有效性
public boolean valid() { return fd != -1; }
强制系统缓冲同步(native方法
public native void sync() throws SyncFailedException;
该类JNI初始化(猜测
private static native void initIDs();
把该Closeable作为父类流联系(实质就是该文件的父路径,只不过用Closeable好描述)
synchronized void attach(Closeable c) { if (parent == null) {//如果没有父类把该类作为直接父类 // first caller gets to do this parent = c; } else if (otherParents == null) {//如果“所有父类”为空则把直接父类和传入父类加入 otherParents = new ArrayList<>(); otherParents.add(parent); otherParents.add(c); } else {//直接加入 otherParents.add(c); } }
关闭所有的拥有该标志符的流(及把该类
synchronized void closeAll(Closeable releaser) throws IOException { if (!closed) {//检测当前标识符从属流是否处于关闭态 closed = true;//设置为已关闭 IOException ioe = null; try (Closeable c = releaser) {//try后括号内容在try执行完后会自动释放 if (otherParents != null) { for (Closeable referent : otherParents) { try { referent.close(); } catch(IOException x) { if (ioe == null) { ioe = x; } else { ioe.addSuppressed(x);//把异常压入异常栈,防止丢失(多层异常捕捉有可能出现异常丢失(一般是finally块出错),压入栈记录) } } } } } catch(IOException ex) { /* * If releaser close() throws IOException * add other exceptions as suppressed. */ if (ioe != null)//内层存在异常就压栈 ex.addSuppressed(ioe); ioe = ex; } finally { if (ioe != null) throw ioe; } } }
存在两个静态代码块:
初始化JNI
static { initIDs(); }
把JavaIOFileDescriptorAccess加入到ShareSecrets中(这句是注释,目测其方法是向系统底层注册该类,将该类与底层链接(主要是句柄的传递)
static { sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess( new sun.misc.JavaIOFileDescriptorAccess() { public void set(FileDescriptor obj, int fd) { obj.fd = fd; } public int get(FileDescriptor obj) { return obj.fd; } public void setHandle(FileDescriptor obj, long handle) { throw new UnsupportedOperationException(); } public long getHandle(FileDescriptor obj) { throw new UnsupportedOperationException(); } } ); }
该类基本很少使用,更多时候我们会直接使用输入输出流。
该类的fd值是系统给的,无法自主修改(不是只有0、1、2。。。系统会给串随机ID,0、1、2是标准系统流)
网上关于该类的文章也有很多,希望深入了解的朋友可以多看看。