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

该类引入了:

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,可以参考我前面写的BufferInputStream

private 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();
}






该类使用非常频繁,也非常方便,推荐大家深入了解


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值