2.IO流的体系和字节输出流FileOutputStream的基本用法
一.IO流的体系:
IO流体系 | 输入流 | 输出流 |
---|---|---|
字节流 | InputStream类即字节输入流,负责读取数据(InputStream中Input译为输入,Stream译为流) | OuputStream类即字节输出流,负责写出数据(OutputStream中Output译为输出,Stream译为流) |
字符流 | Reader类即字符输入流,负责读取数据 | Writer类即字符输出流,负责写出数据 |
-
InputStream类、OutputStream类、Reader类和Writer类都是抽象类,不能直接创建他们的对象,还要看他们的子类,需要用他们的子类创建对象
二.字节流概述:
父类 | 对应的子类 | 对应的子类 | 对应的子类 |
---|---|---|---|
InputStream类 | FileInputStream类:File代表作用即操作本地文件的字节输入流,InputStream就是FileInputStream的父类 | ObjectInputStream类:Object是作用即操作对象的字节输入流, InputStream就是ObjectInputStream的父类 | BufferedInputStream类:Buffered是作用即带有缓冲区的字节输入流,InputStream就是BufferedInputStream的父类 |
OuputStream类 | FileOutputStream类:File代表作用即操作本地文件的字节输出流,OutputStream就是FileOutputStream的父类 | ObjectOutputStream类:Object是作用即操作对象的字节输出流, OutputStream就是ObjectOutputStream的父类 | BufferedOutputStream类:Buffered是作用即带有缓冲区的字节输出流,OutputStream就是BufferedOutputStream的父类 |
三.字节流里OutputStream类的子类FileOutputStream类(字节输出流FileOutputStream):
1.作用:
FileOutputStream流用于操作本地文件的字节输出流,可以把程序中的数据写到本地文件中
2.常用方法:
-
FileOutputStream类只有一个形参的构造方法:
-
FileOutputStream类的write方法和close方法:
3.书写步骤:
步骤一:创建字节输出流对象
步骤二:写出数据
步骤三:释放资源
四.FileOutputStream类(字节输出流)的书写细节:
1.创建字节输出流对象FileOutputStream:
细节1:new对象时构造方法FileOutputStream的参数是字符串表示的路径或者是File对象都是可以的
如果构造方法中传递的是字符串表示的路径:
在底层如果字符串路径不为null的话,还是会new一个File对象,最终再调用本类this的其他构造方法:
如果构造方法中传递的是File对象:
之后调用本类this的其他构造方法:
最终调用的构造方法和传递的是字符串表示的路径调用的构造方法一致。
细节2:如果操作的文件不存在时会创建一个新的文件(和细节1有关),但是要保证父级路径是存在的
FileOutputStream方法传入的是字符串"src\\a.txt",意味着要操作的是a.txt文件,此时在左侧的目录中不存在a.txt文件,但父级路径src存在:
运行上述代码,并没有报错,结果如下:
发现在左侧的目录中自动创建了a.txt文件,同时也写出了数据到a.txt文件中。
但如果FileOutputStream方法传入的是字符串"aaa\\a.txt",意味着要操作的是a.txt文件,此时在左侧的目录中不存在a.txt文件,父级路径aaa也不存在:
运行上述代码:
最终报错,因为父级路径aaa不存在。
细节3:如果要操作的文件已经存在,构造方法则会清空该文件的内容再重新输入数据
提前创建好一个a.txt文件,写入数据abc:
FileOutputStream方法传入的是字符串"a.txt",意味着要操作的是当前模块下的a.txt文件,运行如下代码:
运行结果如下:
控制台没有报错,在a.txt文件中原来的abc被清空,写入了代码中要求要入的a:
2.写出数据:
细节:write方法的参数是整数,但是实际上写到本地文件中的是该整数在ASCII码上对应的字符
因此如果传入参数97到write方法中,那么写入文件的数据就是97对应的字符a。
但如果要把97写入文件中该怎么办呢?首先提取97里的9,看作是字符9即'9',字符9对应的ASCII码为57,再提取97里的7,把7看作是字符7即'7',字符7对应的ASCII码为55,然后依次写入文件即可,
演示如下:
运行上述代码,控制台没有报错,而且a.txt文件中写入了97:
3.释放资源:相当于解除了资源的占用(如果不释放资源就会导致资源一直被占用,使其无法进行其他如删除等操作,因此每次使用完IO流后都需要释放资源)
细节:每次使用完IO流后都需要释放资源
但如果不释放资源,如下:
运行上述代码,如下:
此时程序不停止,资源也没有释放。
由于此时操作的是a.txt文件,右击目录中的a.txt文件->打开于->文件资源管理器:
如下图,右击a.txt文件->删除:
如下图,发现无法删除,因为Java正在占用这个文件,其他人在本地文件中是无法操作的:
现在调用close方法进行释放资源:
运行上述代码,结果如下:
此时程序不停止,但资源已经被释放了。
由于此时操作的是a.txt文件,右击目录中的a.txt文件->打开于->文件资源管理器:
如下图,右击a.txt文件->删除:
此时a.txt文件可以被删除了,因为释放了a.txt的资源了:
总结:
五.字节输出流FileOutputStream实例:
需求:
写出一段文字到本地文件中(暂时不写中文)。
分析:
步骤一:创建字节输出流对象
->创建什么对象,取决于要干什么
->此时要写出一段文字到本地文件中
->其中"写出一段文字",所以就要用输出流,可以用OutputStream类,但OutputStream类是抽象类,不能直接创建它的对象
->还要"到本地文件中",此时就要找OutputStream类的子类中能操作本地文件的类,关于本地文件File即FileOutputStream类
步骤二:写出数据->可以使用write方法
步骤三:释放资源->可以使用close方法
解答:
首先创建本类下的一个a.txt文件:
代码:
package com.itheima.mybytestream;
import java.io.File;
import java.io.IOException;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException {
//在当前模块MyIO下创建一个a.txt文件
/*注:这里的路径要么使用绝对路径D:\Java\MyIO\a.txt,要么使用相对路径a.txt,
MyIO\a.txt是错的 */
File f = new File("a.txt"); //本例使用相对路径
f.createNewFile();
}
}
未运行上述代码时,下述图片中还没有a.txt文件:
运行上述代码后,此时创建了a.txt文件,如下述图片:
创建FileOutputStream类操作a.txt文件:
package com.itheima.mybytestream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException, FileNotFoundException {
//在当前模块MyIO下创建一个a.txt文件
/*注:这里的路径要么使用绝对路径D:\Java\MyIO\a.txt,要么使用相对路径a.txt,
MyIO\a.txt是错的 */
File f=new File("a.txt"); //本例使用相对路径
f.createNewFile();
//1.创建对象
/*创建什么对象,取决于要干什么->此时要写出一段文字到本地文件中
->其中"要写出一段文字",所以就要用输出流,可以用OutputStream类,但OutputStream类是抽象类,不能直接创建它的对象
->还要"到本地文件中",此时就要找OutputStream类的子类中能操作本地文件的类,关于本地文件File即FileOutputStream类 */
//要指定把数据输出到哪个文件中,所以创建FileOutputStream类时要指定文件的路径,FileOutputStream的形参就是指定文件的路径
FileOutputStream fos=new FileOutputStream("a.txt"); //这里用相对路径,表示直接到当前项目下找a.txt文件
//FileNotFoundException异常用于提示让你检查本地文件中是否有a.txt文件,FileNotFoundException的父类是IOException
//2.写出数据
fos.write(97);
/* 使用write方法时需要抛出异常IOException,
此时write方法的形参是int型整数,比如写一个97,
本例中在a.txt文件中输出a,因为97对应的字符为a,a的ASCII码为97 */
//3.释放资源
fos.close();
/* 使用close方法时需要抛出异常IOException */
//最终是把a写到本地文件a.txt文件中,因为97对应的字符为a,a的ASCII码为97
}
}
运行结果:在当前模块下的a.txt文件中输出a
注意事项:
1.上述例子要指定把数据输出到哪个文件中,所以创建FileOutputStream类时需要指定文件的路径,FileOutputStream的形参就是用来指定文件的路径的;
2.创建FileOutputStream对象需要抛出异常FileNotFoundException,FileNotFoundException异常用于提示让你检查本地文件中是否有要操作的文件即FileOutputStream形参里的文件;
3.FileNotFoundException类的父类是IOException;
4.使用write方法时需要抛出异常IOException,上述例子中write方法的形参是int型整数97,最终就会在指定文件中输出a,因为97对应的字符为a,a的ASCII码为97;
4.使用close方法时需要抛出异常IOException。
六.字节输出流FileOutputStream原理:
电脑中有很多文件,此时是如何得知把数据输出到哪个文件呢?其实就是创建FileOutputStream对象时就已经指定了要把数据输出到哪个文件,会根据书写的文件的路径让程序与文件之间建立一个数据传输的通道:
然后通过write方法写出数据,数据相当于在通道中进行传输:
最后调用close方法释放资源的时候,相当于把这个通道销毁: