您的位置:首页 > 编程语言 > Java开发

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

2018-03-06 08:21 274 查看
该类无继承关系,引入了如下包: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;完成了Closeable接口的其他父类链表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作为父类流联系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是标准系统流)
网上关于该类的文章也有很多,希望深入了解的朋友可以多看看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: