Java – IO流 – FileInputStream字节输入流

简介

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。

 

创建输入流

1.创建字节输入流对象

2.读数据

3.释放资源

 

创建对象

// 以字符串形式表达文件目录位置
public FileInputStream(String name);

// 以File 对象的形式表达文件目录位置
public FileInputStream(File name);

注意:如果文件不存在或路径不正确,会直接报错异常。

 

 

读取数据

// 读取一个字节的数据,返回 int 型,以ASCII码转出,每调用一次就读取一个字节,如果已经读到文件尾,会返回 -1
public int read();

// 一次读取多个字节的数据,返回 int 型,返回的数据为读取的数据长度,
读取的多个字节数据会存到数组中,一次读取多少字节,全看这个 byte[] 数组声明
了多少个成员
// 每一次的read 读取中,都会尽可能的覆盖填满 byte[] 字节数组,但如果到了文件
末尾时,数据存不满,那么上一次填充的数据中,有可能依然还在,因此要注意最后
一次读取时的数据处理。
public int read(byte[] b);

 

 

FileInputStream 循环读取

FileInputStream fis = new FileInputStream("Learn\\src\\a.txt");
int b;
while ((b = fis.read()) != -1) {
    System.out.println((char) b);
}

 

 

释放资源

Java在读文件的时候,会对文件进行占用锁定,期间其它程序无法对它进行操作,因此我们对文件操作完成后,应该要对文件进行解锁去除占用。

fis.close();

 

异常中的处理(普通方式)

FileInputStream  中,包含了编译时异常,如果调用FileInputStream 创建构造时,会出现编译错误,需要我们 throws 抛出异常。

同时也可以使用 try...catch  的方式进行处理。

但是 try...catch  中存在两个问题:

问题一:FileInputStream  找不到文件时会直接抛出异常,try 中一旦出现异常时,会停止执行 try 下面的代码,这使得 close()  关闭流这种方法有可能没有执行到。

try {
            // 如果 FileInputStream 出现异常,后面的代码不会执行
            FileInputStream fis = new FileInputStream("不存在的文件");
            // 这里的代码不会被执行,所以 fis.close() 也不会被执行
            fis.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 如果把 fis.close() 放在这里,则因为作用域的原因,会找不到 fis 对象
            fis.close();
        }

解决方法是,把 FileInputStream  创建对象移出 try 作用域外

 

// 把 FileInputStream 创建对象移出作用域名,必须初始化为 null,否则 finally 处的 fis.close 会报编译错误
// 原因是,未初始化的对象不能调用 任何 方法
        FileInputStream fis = null;
        try {
            // 但因 FileInputStream 本身也有编译异常,所以不能在 try 外面 new 
            fis = new FileInputStream("不存在的文件");
            // 这里的代码不会被执行,所以 fis.close() 也不会被执行
            fis.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 如果把 fis.close() 放在这里,则因为作用域的原因,会找不到 fis 对象
            fis.close();
        }

 

 

问题二:假如,try 中的 FileInputStream 创建依然报错,那么 fis 对象依然是null ,这时调用 finally 代码块中的 fis.close()  时,依然会报错

// 把 FileInputStream 创建对象移出作用域名
        FileInputStream fis = null;
        try {
            // 但因 FileInputStream 本身也有编译异常,所以不能在 try 外面 new
            fis = new FileInputStream("不存在的文件");
            // 这里的代码不会被执行,所以 fis.close() 也不会被执行
            fis.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (fis != null){
                fis.close();
            }
        }

解决方法是:在 调用 close()  方法之前,判断 fis 是否为 null

 

异常中的处理(JDK7方式)

Java 也发现了普通方法中处理 close() 是比较麻烦的,所以在JDK 7 后,提供一个自动关闭文件接口 AutoCloseable 方法,FileInputStream 实现了 AutoCloseable 接口,我们不需要手动去调用 close()  方法

用法如下

try(定义字节流1; 定义字节流2) {
            fis... 处理逻辑
            fis2... 处理逻辑
}catch (IOException e){
            
}

在JDK7中,try 多出一个小括号,括号中编写定义字节流的方法,多个字节流定义,使用; 进行分割即可。

try(FileInputStream fis = new FileInputStream("不存在的路径");
     FileInputStream fis2 = new FileInputStream("不存在的路径")) {
            fis... 处理逻辑
            fis2... 处理逻辑
}catch (IOException e){
            
}

不需要调用 close()  方法

 

异常中的处理(JDK9方式)

从JDK7的方案来看,确实比较好,但是在 try()  中传入创建方法,使得代码非常长,不利于阅读,在JDK9 中,Java 允许创建方法在try()  代码块外面定义,try() 中传个对象即可。

FileInputStream fis = new FileInputStream("不存在的路径");
FileInputStream fis2 = new FileInputStream("不存在的路径");
try(fis; fis2) {
            fis... 处理逻辑
            fis2... 处理逻辑
}catch (IOException e){
            
}

多个对象,依然使用 ; 分割即可。

 

示例:复制文件(小文件)

public static void copySmallFile(String src, String to) throws IOException {
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(to);
        int b;
        while ((b = fis.read()) != -1) {
            fos.write(b);
        }
        fos.close();
        fis.close();
    }

 

示例:复制文件(大文件)

public static void copySmallFile(String src, String to) throws IOException {
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(to);
        int len;
        byte[] data = new byte[1024 * 1024 * 10];
        while ((len = fis.read(data)) != -1) {
            // 使用 write() 带偏移参数的方法,读取相对长度的字节
            // 处理当文件读取到末尾时数据填不满byte[]数组读取溢出的问题
            fos.write(data, 0, len);
        }
        fos.close();
        fis.close();
    }

 

 

 

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

THE END
分享
二维码
打赏
海报
Java – IO流 – FileInputStream字节输入流
简介 操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。   创建输入流 1.创建字节输入流对象 2.读数据 3.释放资源   创建对象 // 以字符串形式表达文件目录位置 ……
<<上一篇
下一篇>>