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

Java 日看一类(17)之IO包中的FileInputStream类

2018-03-07 08:22 375 查看
该类引入了:import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;继承了InputStream。

该类的类头注释如下:/**
* A <code>FileInputStream</code> obtains input bytes
* from a file in a file system. What files
* are available depends on the host environment.
*
* <p><code>FileInputStream</code> is meant for reading streams of raw bytes
* such as image data. For reading streams of characters, consider using
* <code>FileReader</code>.
*
* @author Arthur van Hoff
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileOutputStream
* @see java.nio.file.Files#newInputStream
* @since JDK1.0
*/大意如下:
FileInputStream从文件系统的文件中获取输入byte
文件的有效性取决于主机环境
FileInputStream可以直接从原始byte流读取数据(读取出byte数据),例如图像数据
如果要从流中读取字符,请考虑使用FileReader

该类含有如下的成员变量:
文件描述符:private final FileDescriptor fd;输入文件的路径:private final String path;文件流频道:private FileChannel channel = null;线程关闭锁private final Object closeLock = new Object();流关闭标示(每次调用时刷新:private volatile boolean closed = false;

该类含有如下的成员方法:
构造方法(输入文件的路径构造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);//把File类标示的虚拟路径引入
SecurityManager security = System.getSecurityManager();//获得安全控制器
if (security != null) {
security.checkRead(name);//检查路径有效性
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);//将fd与该对象绑定
path = name;
open(name);//打开该文件
}构造方法(文件描述符构造流,仅绑定了描述符序号,没有给出路径public FileInputStream(FileDescriptor fdObj) {
SecurityManager security = System.getSecurityManager();
if (fdObj == null) {
throw new NullPointerException();
}
if (security != null) {
security.checkRead(fdObj);
}
fd = fdObj;
path = null;

/*
* FileDescriptor is being shared by streams.
* Register this stream with FileDescriptor tracker.
*/
fd.attach(this);
}打开并读入输入文件(系统native方法,看不见工作原理private native void open0(String name) throws FileNotFoundException;同上,调用上一个方法private void open(String name) throws FileNotFoundException {
open0(name);
}从数据流中读入byte数据,如果没有输入流,该方法无效(调用下一个native方法public int read() throws IOException {
return read0();
}被上个函数调用的read()方法private native int read0() throws IOException;读取传入的byte数组中特定位置特定长度的数值(还是native,可以参考我前面写的BufferInputStreamprivate native int readBytes(byte b[], int off, int len) throws IOException;读入传入byte数组的全部数值public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}相当于上个native函数的public转化public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}跳过后续读入的n个字符(参考我前面写的各种BufferInputStream类public native long skip(long n) throws IOException;返回当前文章剩余可读取数据(设计思路很清晰,但内部封装无法看出来具体实现public native int available() throws IOException;关闭输入流public void close() throws IOException {
synchronized (closeLock) {//关闭锁
if (closed) {
return;
}
closed = true;
}
if (channel != null) {//流频道不为空
channel.close();
}

fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();//注销文件描述符
}
});
}返回该流的文件描述符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;
}
}jni注册初始化(猜测private static native void initIDs();向jvm注销该对象并释放内存(猜测private native void close0() throws IOException;确认在没有更多数据流入该流中时或该类不能再被使用到后(代码块失效)自动关闭流protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {//存在文件描述符且非标准输入流
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}

静态代码块:static {
initIDs();
}

该类使用非常频繁,也非常方便,推荐大家深入了解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: