File类: 用于描述一个文件或者文件夹的
通过File对象我们可以读取文件或者文件夹的属性数据,如果我们需要读取文件的内容数据,那么我们需要使用IO流技术。
IO流(Input Output)
IO流解决问题: 解决设备与设备之间的数据传输问题。 内存—>硬盘 硬盘—>内存
IO流技术:
IO流分类:
如果是按照数据的流向划分:
输入流
输出流
如果按照处理的单位划分:
字节流: 字节流读取得都是文件中二进制数据,读取到二进制数据不会经过任何的处理。
字符流: 字符流读取的数据是以字符为单位的 。 字符流也是读取文件中的二进制数据,不过会把这些二进制数据转换成我们能 识别的字符。
字符流 = 字节流 + 解码
输入字节流:
--------| InputStream 所有输入字节流的基类 抽象类
------------| FileInputStream 读取文件数据的输入字节流
使用FileInputStream读取文件数据的步骤:
- 找到目标文件
- 建立数据的输入通道。
- 读取文件中的数据。
- 关闭 资源.
//方式一:无法完整的读取一个文件的数据 (已经被淘汰)
public static void inputstreamReadTest1() throws FileNotFoundException, IOException {
//1. 找目标文件
String pathname = "D:\\Java\\testFile\\aa.txt";
File file = new File(pathname);
//2. 建立数据的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
//3. 读取文件中的数据
int content=fileInputStream.read(); //read()读取一个字节的数据,把读取的数据返回
System.out.println("读到的内容是:"+(char)content);
//4. 关闭资源
fileInputStream.close();
}
//方式二:使用循环读取文件信息
public static void inputstreamReadTest2() throws FileNotFoundException, IOException {
// 1. 找目标文件
String pathname = "D:\\Java\\testFile\\英语美文.txt";
File file = new File(pathname);
// 2. 建立数据的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
// 3. 读取文件中的数据
int content = 0; // 声明该变量存储读取的数据
while ((content = fileInputStream.read()) != -1) {
System.out.print((char) content);
}
// 4. 关闭资源
fileInputStream.close();
}
//方式三:使用缓冲数组读取 缺点: 无法读取完整一个文件的数据 (已被淘汰)
public static void inputstreamReadTest3() throws FileNotFoundException, IOException {
// 1. 找目标文件
String pathname = "D:\\Java\\testFile\\英语美文.txt";
File file = new File(pathname);
// 2. 建立数据的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
// 3. 建立缓冲字节数组,读取数据
byte[] buf = new byte[1024*1024]; //相当于超市中的购物车
int length = fileInputStream.read(buf);
// 如果使用read读取数据传入字节数组,那么数据是存储到字节数组中的,而这时候read方法的返回值是表示的是本次读取了几个字节数据到字节数组中。
System.out.println("length:"+ length);
String content = new String(buf,0,length);
System.out.println(content);
// 4. 关闭资源
fileInputStream.close();
}
//**方式四**:使用缓冲数组读取配合循环一起读取 读取时间是:31619 效率高
public static void inputstreamReadTest4() throws FileNotFoundException, IOException {
long startTime =System.currentTimeMillis();
// 1. 找目标文件
String pathname = "D:\\Java\\testFile\\testFind\\赤霞之链 .jpg";
File file = new File(pathname);
// 2. 建立数据的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
// 3. 建立缓冲字节数组,读取数据
byte[] buf = new byte[1024]; //存储读取到的数据 , 缓冲数组长度一般是1024倍数,因为与计算机的处理单位有关,理论上,缓冲数组越大,效率越高
int length = 0; //保存每次读取的字节个数
while((length=fileInputStream.read(buf))!=-1){ //如果read方法读取到文件末尾,那么返回-1表示
System.out.println(new String(buf,0,length));
}
// 4. 关闭资源
fileInputStream.close();
long endTime =System.currentTimeMillis();
System.out.println("读取时间是:"+(endTime-startTime));
}
使用方式四,这种效率高,同时要注意byte[] buf = new byte[1024];
在循环中不停往buf添加数据是覆盖而不是将buf清空后再添加数据。这个需要注意。
System.out.println(new String(buf,0,length));
改成System.out.println(new String(buf));
有可能导致输出不准确
例如在文本中存储了 aaaabbbbccc.
按照第一种可以正常读取,但是如果按照System.out.println(new String(buf));
读取,则会出现aaaabbbbcccb这种情况。
字节流也可以正确读取或输出字符,但是如果缓冲不能一次性将字符读完,则会导致其解码错误,出现乱码。例子:
//使用字节流读取中文
public class Demo2 {
public static void main(String[] args) throws IOException {
File file = new File("D:\\Java\\testFile\\英雄志.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[3];
//这里就会导致出现乱码,如果是byte[] buf = new byte[1024];就会好很多
int length = 0;
while((length = fileInputStream.read(buf))!=-1){
System.out.print(new String(buf,0,length)); //借用字符串的解码功能。
}
}
}