IO流
流:是一连串流动的数据或者是管道。
数据源------<>--------目的地
数据输出的我们称它为数据源,数据输入的我们称它为目的地,以程序(大脑)为中心,数据输入程序,程序就是目的地,数据输出程序,程序就是数据源。
流的分类:
按流向分:输入流和输出流;
按操作单元分:字节流和字符流;
按功能分:节点流和功能流;
节点流:数据直接从数据源到目的地,没有任何外力。
功能流:经过包装。
1、字节流:万能流,所有数据在计算机中都是以字节存储。
InputStream 字节流又可以分为字节输入流和字节输出流。
- 字节输入流InputStream
流向:输入流
操作单元:字节流
功能:节点流
此抽象类是表示字节输入流的所有类的超类,不能实例化。
FileInputStream类继承自InputStream类主要作用是从文件系统中的某个文件中获得输入字节。
public class FileInputStream extends InputStream
读入数据的方法:
read() 每次从输入流中读入一个字节的内容,想要读入多个 手动一个字节一个字节读入,返回值是int型,若没有读到会返回-1。
read(byte[] b) 一个字节数组一个字节数组读入,返回值是int型,若没有读到会返回-1。字节数组的长度可以随意取,但是一般用1024的整数倍。
读数据的流程:
单个字节读入 | 字节数组读入 |
---|---|
1、建立联系 | 1、选择流 |
2、选择流 | 2、准备卡车 |
3、操作(读入) | 3、操作(读入) |
4、关闭 | 4、处理数据 |
5、关闭 |
- 字节输出流OutputStream
此抽象类是表示输出字节流的所有类的超类。
FileOutputStream 文件输出流继承自OutputStream类,作用是用于将数据写入 File的输出流。
注意:如果目的地的文件File不存在,系统会自动创建指定文件,文件夹不会自动创建。
写数据的流程:
1、选择流
2、准备数据
3、写出
4、强制刷出
5、关闭 - 文件拷贝:数据源 --程序-- 目的地
字节输入流和字节输出流既然分别有读入和写出的功能,那么就可以把一个文件的内容读入到指定的文件中去。
过程:就是把输入和输出的过程结合起来
//1.选择流
输入流 InputStream is=new FileInputStream(“D:/test.txt”);
输出流 OutputStream os=new FileOutputStream(“E:/test.txt”);
//2.准备卡车
byte[] car=new byte[1024];
//3.读入写出
int len=-1; //读入到小卡车中数据的个数
while((len=is.read(car))!=-1){
os.write(car,0,len);
}
//4.刷出
os.flush();
//5.关闭 开闭原则:先打开的后关闭
os.close();
is.close();
2、字符流
只能操作纯文本的内容 .txt .html ,
字符流又分为字符输入流和字符输出流。
- 字符输入流Reader
FileReader是Reader的直接子类。
常用方法:
read()返回作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
read(char[]) 将字符读入数组,读取的字符数,如果已到达流的末尾,则返回 -1
close()关闭该流并释放与之关联的所有资源。在关闭该流后,再调用 read()将抛出 IOException。关闭以前关闭的流无效。 - 字符输出流Writer
FileWriter是Writer直接子类。
常用方法:
Writer append(char c) 将指定字符添加到此 writer。
Writer append(CharSequence csq) 将指定字符序列添加到此 writer。
void write(int c) 写入单个字符。
void write(String str) 写入字符串。
abstract void flush() 刷新该流的缓冲
abstract void close() 关闭此流,但要先刷新它。
3、功能流的一种
缓冲流:增强功能,提高性能。
使用:使用时,用功能流包裹节点流。
字节缓冲流:
字节输入缓冲流 BufferedInputStream
字节输出缓冲流 BufferedOutputStream
无新增方法,可以发生多态
代码实现:
InputStream=new BufferedInputStream(new FileInputStream(“D:/test.txt”));
OutputStream=new BufferedOutputStream(new FileOutputStream(“E:/dest.txt”));
字符缓冲流:
不能发生多态,因为父类引用对子类新增方法不可见。
BufferedReader继承自Reader新增方法readLine() 读取一行。
BufferedWriter继承自Writer新增方法newLine() 写出换行符。
代码实现:
BufferedReader read=read=new BufferedReader(new FileReader(“D:/haha.txt”);
BufferedWriter write=new BufferedWriter(new FileWriter(“D:/dest.txt”));
4、转换流(了解)
- 可以把字节流转为字符流使用
InputStreamReader(InputStream,String charset)
OutputSteamWriter(OutputSteam,String charset) - 可能出现乱码的情况:
1.字符编码格式不统一
2.缺少字节个数 - 不同编码格式汉字所占字节大小:
ISO-8859-1 1个字节
GBK 2个字节
GB2312 2个字节
UTF-8 3个字节
5、基本数据类型流
读写带有基本数据类型的数据+String
使用:用基本数据类型流包裹字节节点流
基本数据类型流具有新增方法,不能发生多态。
新增方法是读入指定类型数据,和写出指定类型数据
DataInputStream(InputStream): 新增方法: readXXX()
DataOutputStream(OutputStream): 新增方法: writeXXX()
注意:读入和写出的顺序要一致。
6、对象流
序列化:将对象信息转为可存储或者可传输的信息格式。
序列化输出流:ObjectOutputStream
反序列化输入流:ObjectInputStream
具有新增方法读写指定数据;
注意:
- 先序列化后反序列化。
- 不是所有的类都能序列化。类通过实现 java.io.Serializable 接口以启用其序列化功能。
- 不是所有的属性都需要序列化,把不需要序列化的属性用transient修饰。
- 静态的内容不能被序列化,静态变量不是对象状态的一部分,因此它不参与序列化。所以将静态变量声明为transient变量是没有用处的。
- 如果父类实现了Serializable,子类中所有的内容都可以序列化。
- 如果子类实现Serializable,父类中的内容没有序列化能力,只有子类的内容有。