Java 日看一类(16) 之IO包中的FileDescriptor类

该类无继承关系,引入了如下包:

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是标准系统流)

网上关于该类的文章也有很多,希望深入了解的朋友可以多看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值