FileInputStream详细介绍:
FileInputStream:字节输入流关系图:
构造方法
FileInputStream(File file) 传递一个File对象,来将实际文件进行连接
FileInputStream(String name) 传递一个表示路径的字符串,来将实际文件进行连接
画图理解为:当我们从一个水缸取水时,首先要知道水缸的位置在哪里吧,构造方法就是传递一个文件的地址(水缸的位置)。如果构造方法传递的参数有误就会抛出FileNotFoundException异常
读取文件的方法
方法1: 一个字节一个字节的读
read() 从输入流读取一个字节
主要代码演示:
import java.io.*;
public class Demo {
public static void main(String[] args) throws Exception {
File f = new File("D:\\www\\bin.txt"); //文件的路径
InputStream file = new FileInputStream(f); //构造方法,这里使用了多态
//InputStream file = new FileInputStream("D:\\www\\bin.txt"); 两种方式效果一模一样
int len;
/*
因为 read()方法返回的是读取的一个字节,如果读取到文件的末尾将返回-1
因此我们可以用循环一次读取出文件的每一个字节
*/
while((len = file.read()) != -1) {
System.out.print((char)len); //将字节转换为字符在控制台显示出来
}
}
}
画图理解
从图中我们可以看到这种一个字节一个字节的方式进行读取文件时效率是非常慢的
提升篇
我们可以使用这种方式打印中文字符?
答案当然是不能的
因为read方法每次读取一个字节,而我们的中文字符每个字符是两个字节因此在读取的时候硬把两个字节拆开就会导致乱码。
既然一个字节一个字节的读,效率非常的慢,所以我们就可以一个字节数组的形式进行读写
方法2: 一次读取一个字节数组
read(byte[] b) 一次读取一个字节数组,每次最多读取b.length个字节
代码演示:
import java.io.*;
public class Demo {
public static void main(String[] args) throws Exception {
File f = new File("D:\\www\\bin.txt");
InputStream file = new FileInputStream(f);
byte[] bytes = new byte[1024]; //定义一个字节数组,不是越大越好,一般是1024或者2的n次幂
int len;
/*
read(byte[] b)方法返回的是读取到数组中的字节个数
*/
while((len = file.read(bytes)) != -1) {
System.out.print(new String(bytes,0,len)); //String类的构造方法,不会出现字符重复的现象。
}
}
}
画图理解
深入理解read(byte[] b) 的返回值
//深入理解read(byte[] b)的返回值
byte[] bytes = new byte[2]; //一次读取两个字节
//假设我的文件里内容为: abcde
int len1 = file.read(bytes) //len1 = 2 打印出 ab
int len2 = file.read(bytes) //len2 = 2 打印出 cd
int len3 = file.read(bytes) //len3 = 1 打印出 ed
图解分析
注意事项
一次读取一个字节数组仍尽量不要读取文本文件,否则可能会出现乱码(排除字节数组的大小和文件大小一致)
解释说明
//假设我们读取的文件为:abcde我
byte[] bytes = new byte[2]; //一次读取两个字节会出现乱码,当第三次读取是强行把字符我拆开,导致乱码
byte[] bytes = new byte[7]; //一次读取7个字节不会出现乱码,因为一次就可以把该文本文件读完
下一边文章介绍字符流的输入,来解决中文乱码的问题!