一、什么是流?
二、什么是输入流?
输入流抽象类有两种,分别是InputStream字节输入流和Reader字符输入流
(一)InputStream类
InputStream类是字节输入流的抽象类,是所有字节输入流的父类;
类的具体结构层次如下:
InputStream类中的所有方法遇到错误时都会引发IOException异常,该类常用的方法及说明如表:
注意:并不是inputStream类的所有子类都支持inputStream中定义的方法,入skip()、mark()、reset()等方法只对某些子类有用。
(二)Reader类
java中的字符是Unicode编码,是双字节,而InputStream类是用来出来单字节的,并不适合处理字符,为此,java提供了专门用来处理字符的Reader类,Reader类是字符输入流的抽象类,也是所有字符输入流的父类,Reader类的具体层次结构如下:
注意:
Reader类的read()方法的参数为char类型的数组。另外Reader类还提供了一个ready()方法,该方法用来判断是否准备读取流,其返回值为boolean类型。
三、什么是输出流?
输出流抽象类也有两种,分别是OutputStream字节输出流和Writer字符输出流
(一)OutputStream类
OutputStream类是字节输出流的抽象类,是所有字节输出流的父类,OutputStream类的具体层次如下:
OutputStream类中的所有方法均没有返回值,在遇到错误时会引发IOException异常,该类的常用方法及说明:
(二)Writer类
writer类是字符输出流的抽象类,是所有字符输出流的父类,Writer类的层次结构如下:
Writer类的常用方法及说明如下:
四、File类
(一)创建文件对象
(二)File类的使用
(三)文件操作
(三)文件夹操作
五、文件输入/输出流
程序运行期间,大部分数据都被存储在内存中,当程序结束或被关闭时,存储在内存中的数据将会消失,如果需要永久保存数据,最好的方法就是把数据保存到磁盘的文件中,为此提供以下类
(一)FileInputStream类与FileOutputStream类
FileInputStream类:读取文件内容使用;
FileOutputStream类:向文件中写入内容使用
案例剖析:
public class FileStreamTest {
public static void main(String[] args) {
File file = new File("word.txt"); // 创建文件对象
try { // 捕捉异常
// 创建FileOutputStream对象,用来向文件中写入数据
FileOutputStream out = new FileOutputStream(file);
// 定义字符串,用来存储要写入文件的内容
String content = "你见过洛杉矶凌晨4点的样子吗?";
// 创建byte型数组,将要写入文件的内容转换为字节数组
byte buy[] = content.getBytes();
out.write(buy); // 将数组中的信息写入到文件中
out.close(); // 将流关闭
} catch (IOException e) { // catch语句处理异常信息
e.printStackTrace(); // 输出异常信息
}
try {
// 创建FileInputStream对象,用来读取文件内容
FileInputStream in = new FileInputStream(file);
byte byt[] = new byte[1024]; // 创建byte数组,用来存储读取到的内容
int len = in.read(byt); // 从文件中读取信息,并存入字节数组中
// 将文件中的信息输出
System.out.println("文件中的信息是:" + new String(byt, 0, len));
in.close(); // 关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
}
(二)文件字符流:FileReader类与FileWriter类
使用字符流,写文件时会避免乱码的产生。
案例剖析:
public class Demo1 {
public static void main(String[] args) {
File f = new File("E:\\untitled\\src\\cn\\tx\\Exceriser200\\text005\\word.txt");
/*
FileWriter fw = null;
String st = "天行健,自强不息;地势坤,厚德载物";
try {
//加true 表示在源文件后追加新内容
fw = new FileWriter(f,true);
fw.write(st);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fw != null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}*/
FileReader fr = null;
try {
fr = new FileReader(f);
//创建缓冲区 读取数据
char ch[] = new char[1024];
//已经读出的字符数
int count;
//循环读取文件中的数据 直到所有字符都读完
while((count = fr.read(ch))!=-1){
System.out.println("文件中的内容为:"+new String(ch,0,count));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五、带缓存的输入/输出流
(一)BufferedInputStream与BufferedOutputStream
案例剖析:
public class BufferedStreamTest {
public static void main(String args[]) {
// 定义字符串数组
String content[] = { "你不喜欢我,", "我一点都不介意。", "因为我活下来,", "不是为了取悦你!" };
File file = new File("word.txt"); // 创建文件对象
FileOutputStream fos = null; // 创建FileOutputStream对象
BufferedOutputStream bos = null; // 创建BufferedOutputStream对象
FileInputStream fis = null; // 创建FileInputStream对象
BufferedInputStream bis = null; // 创建BufferedInputStream对象
try {
fos = new FileOutputStream(file); // 实例化FileOutputStream对象
bos = new BufferedOutputStream(fos); // 实例化BufferedOutputStream对象
byte[] bContent = new byte[1024]; // 创建可以容纳1024个字节数的缓冲区
for (int k = 0; k < content.length; k++) { // 循环遍历数组
bContent = content[k].getBytes(); // 将遍历到的数组内容转换为字节数组
bos.write(bContent); // 将字节数组内容写入文件
}
System.out.println("写入成功!\n");
} catch (IOException e) { // 处理异常
e.printStackTrace();
} finally {
try {
bos.close(); // 将BufferedOutputStream流关闭
fos.close(); // 将FileOutputStream流关闭
} catch (IOException e) {
e.printStackTrace();
}
}
try {
fis = new FileInputStream(file); // 实例化FileInputStream对象
bis = new BufferedInputStream(fis); // 实例化BufferedInputStream对象
byte[] bContent = new byte[1024]; // 创建byte数组,用来存储读取到的内容
int len = bis.read(bContent); // 从文件中读取信息,并存入字节数组中
// 输出文件数据
System.out.println("文件中的信息是:" + new String(bContent, 0, len));
} catch (IOException e) { // 处理异常
e.printStackTrace();
} finally {
try {
bis.close(); // 将BufferedInputStream流关闭
fis.close(); // 将FileInputStream流关闭
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
(二)BufferedReader与BufferedWriter
1、BufferedReader类的常用方法
2、BufferedWriter类的常用方法
3、案例剖析
public class Demo4 {
public static void main(String[] args) {
File file = new File("word.txt");
/* 写入内容到文件里 */
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(file);
//将文本字符输出流包装成缓冲字符流
bw = new BufferedWriter(fw);
String str1 = "世界这么大";
String str2 = "我想去看看";
//第一行的数据
bw.write(str1);
//创建新行
bw.newLine();
//第二行的数据
bw.write(str2);
} catch (IOException e) {
e.printStackTrace();
}finally {
//要注意流的关闭顺序,先创建后关闭
if(bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fw != null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* 读取文件里内容 */
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(file);
//将文本字符输入流包装成缓冲字符输入流
br = new BufferedReader(fr);
String tem = null;
int i = 1;
while ((tem = br.readLine()) != null){
System.out.println("第"+i+"行:"+tem);
i++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br !=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
六、难点解答
(一)字节流和字符流的区别
字节流都是以Stream结尾的,而字符流是以Reader或Writer结尾的。字符流是按照字符来读、写的,所有擅长处理文本信息。字节流是按照最小的字节来读、写的,所以字节流可以处理所有的数据流,但功能没有字符流多。
(二)输入/输出流的使用
以内存为参照对象,当数据从文件流入到内存时,需要使用输入流;当数据从内存流出到文件时,需要使用输出流(将数据打印在显示器上就是一种)