概述
FileInputStream 继承于 InputStream 类。
可以参考 InputStream 的源码:http://blog.csdn.net/yx0628/article/details/79343633
属性
// 文件描述类,处理打开的文件
private final FileDescriptor fd;
// 文件的路径,如果该流是通过文件描述类创建的,该属性则为空
private final String path;
// 用于读、写、映射、操作文件的通道
private FileChannel channel = null;
// 一个关闭锁,只在close()方法中使用,确保多线程同步调用,同时和其他同步方法不冲突(因为这个关闭锁是自己的对象锁)
private final Object closeLock = new Object();
// 流是否是关闭的,volatile保证多线程的可见性
private volatile boolean closed = false;
构造函数
// 文件路径创建File对象,并调用下边的重载的构造函数
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
// 根据File对象来构造文件输入流
public FileInputStream(File file) throws FileNotFoundException {
// 获取文件路径
String name = (file != null ? file.getPath() : null);
// 获取系统的安全管理器
SecurityManager security = System.getSecurityManager();
if (security != null) {
// 确保有文件的读取权限
security.checkRead(name);
}
if (name == null) {
// 文件路径为null,抛出空指针异常
throw new NullPointerException();
}
if (file.isInvalid()) {
// 如果file对象无效,抛出未找到文件异常
throw new FileNotFoundException("Invalid file path");
}
// 创建文件描述符
fd = new FileDescriptor();
// 在文件描述符中保存该对象引用
fd.attach(this);
// 路径名赋值path
path = name;
// 打开该路径进行读取
open(name);
}
// 调用open0(name)本地方法
private void open(String name) throws FileNotFoundException {
open0(name);
}
// 本地方法,打开指定路径的文件进行读取
private native void open0(String name) throws FileNotFoundException;
// 根据文件描述符构造输入流
public FileInputStream(FileDescriptor fdObj) {
SecurityManager security = System.getSecurityManager();
if (fdObj == null) {
throw new NullPointerException();
}
if (security != null) {
security.checkRead(fdObj);
}
// 文件描述符对象属性的赋值
fd = fdObj;
path = null;
// 在文件描述符中保存该对象引用
fd.attach(this);
}
重要方法
read()
// 从输入流中读取下一个字节的数据,调用本地方法
// 该方法一直阻塞直到有可用的数据
public int read() throws IOException {
return read0();
}
// 本地方法,读取下一个字节的数据
private native int read0() throws IOException;
带参数read
可以参考 InputStream 的类似的 read 方法
// 读取b.length数量的字节,并从字节数组b的0下标开始填满b数组
public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}
// 读取b.length数量的字节,并从字节数组b的off下标位置开始填满b数组
public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}
// 本地方法
private native int readBytes(byte b[], int off, int len) throws IOException;
其他本地方法
// 本地方法,跳过n个字节
public native long skip(long n) throws IOException;
// 本地方法,返回可读的字节数
public native int available() throws IOException;
close()
public void close() throws IOException {
// 使用对象锁
synchronized (closeLock) {
// 如果流已经关闭则返回
if (closed) {
return;
}
// 否则将关闭状态设为true
closed = true;
}
// 操作文件的通道不为空,也要进行关闭
if (channel != null) {
channel.close();
}
// 文件描述符相关资源的关闭,并调用本地关闭方法关闭流
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}
private native void close0() throws IOException;
finalize()
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
// 如果fd正在被其他流使用,就不能进行关闭,只有当所有流都不再引用这个文件描述符才关闭
close();
}
}
其他方法
// 获取流对象对应的文件描述符
public final FileDescriptor getFD() throws IOException {
if (fd != null) {
return fd;
}
throw new IOException();
}
// 获取流对象对应的通道,如果为空就创建一个新的通道
public FileChannel getChannel() {
synchronized (this) {
if (channel == null) {
channel = FileChannelImpl.open(fd, path, true, false, this);
}
return channel;
}
}
private static native void initIDs();
// 这个静态块在类加载时调用
// 设置类中属性的内存地址偏移量,便于在必要时操作内存给它赋值
static {
initIDs();
}
最后
以上就是刻苦斑马为你收集整理的Java中IO框架——FileInputStream源码解析属性构造函数重要方法的全部内容,希望文章能够帮你解决Java中IO框架——FileInputStream源码解析属性构造函数重要方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复