最近学IO流学的云里雾里的,虽然之前有学过一遍,但是都忘得七七八八了,再加上深度增加了,挺吃力的。希望这篇博客可以打通他们之间的关系。
流的输入和输出,读和写很容易搞得很混乱,但是从体系上把握会好点
文章目录
- 1 流的分类与理解
- 1.1 OutputStream(输入流)和Writer(写)
- 1.2 FileOutputStream(文件输出流)和FileWriter
- 1.2.1 简介
- 1.2.2 构造方法
- 1.2.3 方法
1 流的分类与理解
流的体系很大,下面有很多子类
- 字节流的抽象基类:InputStream输入流,OutputStream输出流
- 字符流的抽象基类:Reader(读),Writer(写)
这些体系的子类都已基类名作为后缀,而且子类名的前缀就是该对象的功能
字节流和字符流的操作方式几乎一样,字节流的操作数据单元是字节,字符流的操作数据单元是字符。
1.1 OutputStream(输入流)和Writer(写)
从java程序的角度向其写入数据为输出流,下面通过API来学习
OutputStream和Writer类的简介:
OutputStream类的方法:
Writer类的方法
1.2 FileOutputStream(文件输出流)和FileWriter
由于OutputStream和Writer为抽象类,无法实例化,所以需要研究具体实现类,如果输出流是一个文件,就叫文件输出流
1.2.1 简介
1.2.2 构造方法
public class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个可以往文件中写入字符数据的字符输出流对象
/*
* 如果文件不存在,则会自动创建
* 如果文件存在,则会被覆盖
*/
FileWriter fw = new FileWriter("demo.txt");
/*
* write(String)方法
* 其实数据写入到临时存储缓冲区中
*/
fw.write("henghengaijianghui");
/*
* 进行刷新,将数据直接写入到目的地
*/
fw.flush();
/*
* 关闭流,关闭资源
*/
fw.close();
}
}
写入之前文件中内容为:
写入之后文件中内容为:
由此,如果构造方法为第一个,之后写入文件中的数据会把原有的数据覆盖掉
代码:
public class FileWriterDemo2
{
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException
{
//使用构造方法实现对文件的追加续写
FileWriter fw = new FileWriter("demo.txt",true);
fw.write("henghengai"+LINE_SEPARATOR+"jianghui");
fw.close();
}
}
写入之前文件中内容为:
写入之后文件中内容为:
由此,如果构造方法为第二个,写入文件中的数据是在原有文件数据的基础上继续追加续写。
1.2.3 方法
两者都与父类中的方法相同没有额外增加方法:
OutputStream类中的方法:
Writer类中的方法:
注意:两个类的方法有点区别,使用时很容易搞混的,字节输出流的write()方法中只能写入字节数组或者是单个字节。but字符输出流的write()方法除了可以写入单个字符和字符数组以外,还可以写入字符串或字符串的一部分。将字符串转为字节数组的方法:
代码:
public class FileOutputStreamDemo
{
public static void main(String[] args) throws IOException
{
//创建字节输出流对象
//public FileOutputStream(String name)
FileOutputStream fos = new FileOutputStream("fos.txt");
//写数据
//write(byte[] b)
//先把字符串转为字节数组,因为字节输出流只能写入字节数组或者单个字节
fos.write("hello,io".getBytes());
//释放资源
//关闭此文件输出流并释放与此流有关的所有系统资源
fos.close();
}
}
代码:
public class FileOutputStreamDemo1
{
public static void main(String[] args) throws IOException
{
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
//调用write()方法,向文件中写入数据
//write(int b)
fos.write(97);
//write(byte[] b)
byte[] bys = {97,98,99,100,101};
fos.write(bys);
//write(byte[] b,int off,int len)
fos.write(bys, 1, 3);
//释放资源
fos.close();
}
}
代码:
注意:对于字符输出流,因为电脑中文件中的数据都是以字节的形式保存的,而字符占用两个字节,所以进不到文件中,而是在缓冲区中,需要刷新一下,也就是说,每写入一次数据都要刷新一下才能把数据从缓冲区刷新到文件中,但是如果觉得麻烦,可以在最后使用close()方法,因为close()方法调用时默认先刷新。
public class OutputStreamWriter
{
public static void main(String[] args) throws IOException
{
//创建对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw2.txt"));
//写入数据
//write(int c ):写一个字符
osw.write('a');
osw.write(97);
osw.flush();
//write(char[] cbuf):写一个字符数组
char[] chs = {'a','b','c'};
osw.write(chs);
osw.flush();
//write(char[] cbuf,int off,int len)写一个字符数组的一部分
char[] chs = {'a','b','c'};
osw.write(chs, 0, 1);
osw.flush();
//write(String str)写一个字符串
osw.write("我爱郑爽");
osw.flush();
//write(String str,int off,int len)写一个字符串的一部分
osw.write("我爱郑爽",2,2);
//此时不需要使用flush()方法了
//释放资源
//关闭此流,但要先刷新它,在使用此方法之前会先调用flush()方法
osw.close();
}
}