Java I/O学习(二) - FileInputStream

FileInputStream 有两个常用的构造函数

构造函数1

public FileInputStream(String name) throws FileNotFoundException {
	this(name != null ? new File(name) : null);
}

参数 name 表示文件的路径。通过这个传入的路径打开实际的文件。
可以看到其中调用了this方法,这个方法是什么呢?其实就是另外一个构造函数。

构造函数2

public FileInputStream(File file) throws FileNotFoundException {
	// 处理 file 参数为空的情况
    String name = (file != null ? file.getPath() : null);
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkRead(name);
    }
	// 处理null 
    if (name == null) {
        throw new NullPointerException();
    }
	// 查看file是否合法
    if (file.isInvalid()) {
        throw new FileNotFoundException("Invalid file path");
    }
    fd = new FileDescriptor();
    fd.incrementAndGetUseCount();
    this.path = name;
	// 调用 native 方法打开文件
    open(name);
}

构造器很简单,传入参数为File对象,然后对file对象进行一些处理,在将文件路径(file.getPath())传入 native 方法打开实际的文件。

FileInputStream 的读入方法

FileInputStream有多个read的方法可供调用

read方法1:只读取一个字节

public int read() throws IOException {
    Object traceContext = IoTrace.fileReadBegin(path);
    int b = 0;
    try {
        b = read0();
    } finally {
        IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
    }
    return b;
}

正如代码所示,这个方法每一次只返回一个字节。返回值是这个字符的ASCII码。

使用示例

public static void main(String[] args) {
    String filePath = "F:\\FilesExample\\A.txt";
    try ( FileInputStream fis = new FileInputStream(filePath)){

        System.out.println( fis.read() );

    } catch (IOException e) {
        e.printStackTrace();
    }
}

如果读到的字符是大写字母A的话,返回的ASCII码就是65,如果读到的字符是数字1的话,返回的ASCII码就是49.

read方法2:读取指定数组长度到该数组中

public int read(byte b[]) throws IOException {
    Object traceContext = IoTrace.fileReadBegin(path);
    int bytesRead = 0;
    try {
        bytesRead = readBytes(b, 0, b.length);
    } finally {
        IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
    }
    return bytesRead;
}

方法传入一个字节数组,方法调用了readBytes(b, 0, b.length)方法,它是一个native方法。
方法的第一个参数是的数组,待会儿会把读取出来的数据放在这个数组中,第二个是偏移量(关于偏移量:详解Java IO中的偏移量),第三个是数组长度,也就是需要读取多长的数据。
返回值是最后一个字符的坐标位置,如果已经到了最后一个字符还要继续读取的话,就会返回-1.
换句话说,只要接收到-1,就表示流已经读完了。

使用示例

public static void main(String[] args) {
    String filePath = "F:\\FilesExample\\A.txt";
    try ( FileInputStream fis = new FileInputStream(filePath)){

        byte[] bytes = new byte[10];
        System.out.println("最后一个字符的坐标:"+ fis.read(bytes));
        for (int i = 0; i < bytes.length; i++) {
            System.out.println("数组中第"+i+"项内容:"+bytes[i]);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

假设现在A.txt文件中的内容如下:

ABCDEFG

那么这个示例的打印结果就是:

最后一个字符的坐标:7
数组中第0项内容:65
数组中第1项内容:66
数组中第2项内容:67
数组中第3项内容:68
数组中第4项内容:69
数组中第5项内容:70
数组中第6项内容:71
数组中第7项内容:0
数组中第8项内容:0
数组中第9项内容:0

可以发现数组中没有填满的地方都是使用的默认值0。

现在假设要传入的byte数组只有2个长度,结果会是什么样呢?

改造main方法

public static void main(String[] args) {
    String filePath = "F:\\FilesExample\\A.txt";
    try ( FileInputStream fis = new FileInputStream(filePath)){

        byte[] bytes = new byte[2];
        System.out.println("最后一个字符的坐标:"+ fis.read(bytes));
        for (int i = 0; i < bytes.length; i++) {
            System.out.println("数组中第"+i+"项内容:"+bytes[i]);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

结果如下:

最后一个字符的坐标:2
数组中第0项内容:65
数组中第1项内容:66

看结果可以得出结论,我们传入的数组长度为2,read方法也只会读取2个字符。

read方法3:从指定位置读取指定长度的数据存放到指定数组

public int read(byte b[], int off, int len) throws IOException {
    Object traceContext = IoTrace.fileReadBegin(path);
    int bytesRead = 0;
    try {
        bytesRead = readBytes(b, off, len);
    } finally {
        IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
    }
    return bytesRead;
}

几个参数的含义已经在方法2中解释过了,这个方法最后也会调用和方法2相同的native的方法。

应用:读取指定文件内容

在上一篇文章中,我们使用FileOutputStream 字节输出流将内容输出到了指定文件中,现在我们利用 FileInputStream 字节输入流再将内容从文件中读取出来并打印在控制台上。
public static void main(String[] args) {
String filePath = “F:\FilesExample\A.txt”;

    // 创建字节输入流
    try ( FileInputStream fis = new FileInputStream(filePath)){

        // 创建装数据的数组
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes)) != -1){
            // 将读出的数据转换成字符串
            System.out.println(new String(bytes));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

打印结果:

This is FileOutputStreamTest Content  

在进行读数据的时候,采取了三种read方法中的一种。有时间可以试试其他两种。


技 术 无 他, 唯 有 熟 尔。
知 其 然, 也 知 其 所 以 然。
踏 实 一 些, 不 要 着 急, 你 想 要 的 岁 月 都 会 给 你。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值