IO流概念
流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出
IO流的分类
按流的流向不同分为:输入流,输出流
- 输入流:从别的地方获取资源 输入到 我们的程序中(只读)
- 输出流:从我们的程序中 输出到 别的地方(只写)。
按流的数据单位可以分为:字节流,字符流
- 字节流:以字节为单位读写数据,当传输的资源有中文时,可能会出现乱码。
- 字符流:以字符为单位读写数据,有中文时,使用该流就可以正确传输显示中文。
1.ASCII码和 Unicode 编码中,一个英文为一个字节,一个中文为两个字节。
2.UTF-8 编码中,一个英文字为一个字节,一个常用中文为三个字节。
3.Java的字符是Unicode的,所以字符流的一个字符占两个字节
按流的功能不同分为:节点流,处理流
- 节点流:程序用于直接操作目标设备所对应的类。
- 处理流:程序通过一个间接流类去连接和封装节点流,以达到更加灵活方便地读写各种类型的数据。
Io流的基类:
输入流 | 输出流 | |
---|---|---|
字节流 | InputStream | OutputStream |
字符流 | Reader | Writer |
基类中定义了一些基本共性功能方法:
InputStream的常用方法
1.abstract int read():从输入流读一个字节。 如果到达流的末尾,则返回-1 。抽象方法 子类必须提供这个方法的实现。
2.int read(byte[] b): 将输入流中最多 b.length个字节读入 b数组 ,返回实际读的字节数。如果到达流的末尾,则返回-1 。
3.int read(byte[] b, int off, int len): 从偏移量 off开始将输入流中最多 len 个字节读入 byte 数组 ,返回实际读的字节数。如果到达流的末尾,则返回-1 。
4.close():关闭此输入流并释放与该流关联的所有系统资源
OutputStream的常用方法
1.abstract void write(int b):将一个字节写入输出流。b对应.ASCII码的一个字节
2.void write(byte[] b):将最多 b.length 个字节从byte 数组写入输出流3. void write(byte[] b, int off, int len):byte 数组从偏移量 off 开始将最多 len 个字节写入此输出流 4. void flush():刷新此输出流并强制写出所有缓冲的输出字节 5. void close(): 关闭此输出流并释放与此流有关的所有系统资源
Reader的常用方法
1.int read():从输入流读一个字符。 如果到达流的末尾,则返回-1 。
2.int read(char[] cbuf): 将输入流中最多 cbuf.length个字符读入 cbuf数组 ,如果到达流的末尾,返回-1 。
3.abstract int read(char[] cbuf, int off, int len): 从偏移量 off开始将输入流中最多 len 个字节读入cbuf数组 ,如果到达流的末尾,返回-1 。抽象方法子类实现。
4.abstract void close():关闭该流并释放与之关联的所有资源,抽象方法子类实现。
Writer的常用方法
1.void write(char[] cbuf)::将 cbuf数组写入输出流
2.abstract void write(char[] cbuf, int off, int len):cbuf数组从偏移量 off 开始将最多 len 个字符写入输出流
3.void write(int c):将一个字符写入输出流。
4.void write(String str):将一个字符串写入输出流。
5.void write(String str, int off, int len) 字符串从偏移量 off 开始将len 个字符写入输出流
6.Writer append(char c) :追加指定字符到此 writer
7.Writer append(CharSequence csq):追加指定字符序列到此 writer
8.Writer append(CharSequence csq, int start, int end):追加字符序列的子序列添加到此 writer
9.abstract void flush() :刷新该流的缓冲
10.abstract void close(): 关闭此流,但要先刷新它
如何选择IO流
首先我们要明确你操作的是什么(磁盘:文件 ,内存:数组,字符串,网络:管道(进程间通信) )?需要使用字节流还是字符流,是读还是写。这样我们就可以确定要使用的节点流
确定节点流后,再明确是否需要额外功能(处理流封装节点流)
- 需要转换—— 转换流 InputStreamReader 、OutputStreamWriter
- 需要高效—— 缓冲流Bufferedxxx
- 多个源—— 序列流 SequenceInputStream
- 对象序列化—— ObjectInputStream、ObjectOutputStream
- 保证数据的输出形式—— 打印流PrintStream 、Printwriter
- 基本数据,保证字节原样性——DataOutputStreamDataInputStream
如何使用IO流
第一步:创建对应的流,第二步:设置缓冲区(可以不设置,建议设置可以提高效率),第三步:读写操作,第四步:关闭流 。
IO流的应用
拷贝文件(图片,视频,音频等)
public static void main(String[] args) {
//文件路径
String path="C:\\Users\\Administrator\\https://gitee.com/li-jie-jie/pictures/raw/master/javaSE\\Screenshots";
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
//第一步:创建一个文件输入流和输出流,为提高效率用BufferedInputStream封装。
bis= new BufferedInputStream(new FileInputStream(new File(path+"\\1.jpg")));
bos = new BufferedOutputStream( new FileOutputStream(new File(path+"\\2.jpg")));
//第二部:设置缓冲区
byte[] bytes=new byte[1024];
int len=0;
//第三步拷贝文件
while ((len=bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//第四步:关闭资源
if (bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
如果是文本,为避免中文乱码问题,建议大家使用字符流,将上述代码的字节流,改为字符流即可。
将java对象存到磁盘再从磁盘中取出
public static void main(String[] args) {
String path="C:\\Users\\Administrator\\https://gitee.com/li-jie-jie/pictures/raw/master/javaSE\\Screenshots";
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(new File(path+"\\obj.dat")));
ois = new ObjectInputStream(new FileInputStream(new File(path + "\\obj.dat")));
oos.writeObject(new Preson("路飞", 18,"男"));
oos.flush();
oos.writeObject(new Preson("娜美", 16,"女"));
oos.flush();
oos.writeObject(new Preson("乔巴", 10,"男"));
oos.flush();
Preson luFei = (Preson)ois.readObject();
Preson naMei = (Preson)ois.readObject();
Preson qiaoBa = (Preson)ois.readObject();
System.out.println(luFei);
System.out.println(naMei);
System.out.println(qiaoBa);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Preson类需要实现Serializable接口
public class Preson implements Serializable {
private String name;
private int age;
private String sex;