作者:zuoxiaolong8810(左潇龙),转载请注明出处。
设计模式系列结束,迎来了LZ第一篇关于JAVA虚拟机的文章,这一系列文章不再像之前的设计模式一样,有着严格的约束力,本系列文章相对会比较随性,本次LZ就跟各位分享一个关于FileInputStream的小秘密。
在探究这个秘密之前,各位如果没有openjdk的源码,可以去LZ的资源先下载下来,链接是:JVM源码 和 JDK源码
由于资源有最大60MB的限制,所以LZ分成了两部分,一个是JVM的源码,一个是JDK中的源码,而本地方法的源码都在JDK的那个压缩包当中,全部源码下载在openjdk的官网上也有,各位也可以去那里找一下,如果嫌麻烦的话,就去LZ的资源里下载即可。
现在源码我们已经有了,可以来看下我们研究的小秘密了。大家都知道我们在读取文件时离不开FileInputStream这个类,那么不知道各位有没有好奇过,我们的FileInputStream是如何建立的呢?
我们一起先来看看FileInputStream的源码,我们平时都是通过new FileInputStream(name or File)的方式得到的文件输入流,所以我们来看FileInputStream的构造方法。
public
class FileInputStream extends InputStream
{
/* File Descriptor - handle to the open file */
private FileDescriptor fd;
private FileChannel channel = null;
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
//这个方法是我们创建文件输入流时的方式
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) {
throw new NullPointerException();
}
fd = new FileDescriptor();
open(name);
}
我们忽略安全管理器的检查,可以看到,在创建一个文件输入流时,主要做了两件事,
一个是new一个FileDescriptor(文件描述符),一个便是调用了open方法。
不过在此之前,其实还调用了一个方法,在FileInputStream源码的下方,有这样一个静态块。
static {
initIDs();
}
它将在第一次加载FileInputStream类的时候,调用一个静态的initIDs的本地方法,这里我们不跟踪这个方法的源码,它并不是我们的重点,
它的作用是设置类中(也就是FileInputStream)的