1 什么是流
流:内存与存储设备之间的数据传输通道。
2 流的分类
2.1 按方向分【重点】
输入流、输出流
输入流:将<存储设备>中的数据读取到<内存>中。
输出流:将<内存>中的数据写入到<存储设备>中。
2.2 按单位分
字节流、字符流
字节流:以字节为单位,可以读写所有数据。
字符流:以字符为单位,只可以读写文本数据。
2.2 按功能分
节点流、过滤流
节点流:具有实际传输数据的读写功能。(底层流)
过滤流:在节点流的基础上增强功能。
3 字节流
- 字节流的父类(抽象类):
- InputStream:字节输入流
public int read(){}
public int read(byte[] b){}
public int read(byte[] b,int off,int len){}
-
- OutputStream:字节输出流
public int write(int n){}
public int write(byte[] b){}
public int write(byte[] b,int off,int len){}
3.1 文件字节流
- FileInputStream:
- public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
- FileOutputStream:
- public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
FileInputStream
import java.io.FileInputStream;
/**
* 演示FileInputStream的使用
* 演示文件字节输入。
*/
public class Demo01 {
public static void main(String[] args) throws Exception {
//创建FileInputStream对象,并指定文件路径
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//2读取文件
//单个读取
// int date=0;
// while ((date= fis.read())!=-1){
// System.out.print((char) date);
// }
//数组读取
byte[] read2 = new byte[1024];
int count =0;
while ((count= fis.read(read2))!=-1){
System.out.print(new String(read2,0,count));
}
//关闭
fis.close();
System.out.println("\n执行完毕");
}
}
FileOutputStream
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 演示文件字节输出流。
* FileOutputStream
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
//创建文件字节输出流
FileOutputStream outputStream = new FileOutputStream("d:\\bbb.txt",true);
//写入文件
// outputStream.write('d');
// outputStream.write('e');
// outputStream.write('f');
String s ="helloWord";
outputStream.write(s.getBytes());
//关闭
outputStream.close();
System.out.println("\n执行完毕");
}
}
实战
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 实现文件内容的复制
*/
public class Demo03 {
public static void main(String[] args) throws IOException {
//创建输入输出对象
FileInputStream aaaIn = new FileInputStream("D:\\001.jpg");
FileOutputStream bbbOut = new FileOutputStream("D:\\bbb.jpg");
//进行数据读取、写入
byte[] date = new byte[1024];
int count;
int i=1;
while ((count=aaaIn.read(date))!=-1){
System.out.println(i++);
bbbOut.write(date,0,count);
}
//关闭
aaaIn.close();
bbbOut.close();
System.out.println("执行完毕");
}
}
字节缓冲流
- 缓冲流:BufferedInputStream/BufferedOutputStream
- 提高IO效率,减少访问磁盘的次数;
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
BufferedInputStream
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 使用字节缓冲流读取文件
* BufferedInputStream
*/
public class Demo04 {
public static void main(String[] args) throws IOException {
//创建对象
FileInputStream fis = new FileInputStream("D:\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//读取数据
// int date;
// while ((date=bis.read())!=-1){
// System.out.print((char) date);
// }
// System.out.println();
byte[] buf=new byte[1024];
int count=0;
while ((count=bis.read(buf))!=-1){
System.out.print(new String(buf,0,count));
}
System.out.println();
//关闭
bis.close();
System.out.println("执行完毕");
}
}
BufferedOutputStream
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 使用字节缓冲流写入文件
* BufferedOutputStream
*/
public class Demo05 {
public static void main(String[] args) throws IOException {
//创建对象
FileOutputStream fos = new FileOutputStream("d:\\bbb.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写入对象
for (int i = 0; i < 10; i++) {
bos.write("Hello word!\r\n".getBytes());//写入8K缓冲区
}
bos.flush();//刷新到硬盘
//关闭
bos.close();//内部自动调用flush方法
System.out.println("执行完毕");
}
}
对象流:ObjectOutputStream/ObjectIntputStream
- 增强了缓冲区功能。
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象功能:
- readObject() 从流中读取一个对象 反序列化
- writeObject(Object obj) 像流中写入一个对象 序列化
tips:使用流传输对象的过程称为序列化、反序列化
学生类
import java.io.Serializable;
/**
* 学生类
*/
public class Student implements Serializable {
//序列化版本号ID
public static final long serialVersionUID = 100L;
private String name;
private transient int age;
public static String country = "中国";
public Student(){
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
序列化
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
* 使用ObjectOutputStream实现对象序列化
* 注意事项:
* (1)序列化类必须实现Serializable接口(该接口只是一个标记接口,没有任何方法)
* (2)序列化类中的对象属性要求实现Serializable接口
* (3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类
* (4)使用Transient(瞬间的/瞬时的)修饰属性,这个属性不能序列化。
* (5)静态属性不能序列化
* (6)可以序列化多个对象,可以借助集合实现
*/
public class Demo06 {
public static void main(String[] args) throws IOException {
//创建对象
FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student s1 = new Student("张三", 18);
Student s2 = new Student("李四", 18);
//写入数据(序列化)
// oos.writeObject(s1);
// oos.writeObject(s2);
ArrayList<Student> students = new ArrayList<>();
students.add(s1);
students.add(s2);
oos.writeObject(students);
//关闭
oos.close();
System.out.println("序列化完毕");
}
}
反序列化
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
/**
* 使用ObjectInputStream实现对象反序列化 //把文件读取到内存中重构成对象
*/
public class Demo07 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建对象
FileInputStream fis = new FileInputStream("d:\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//读取文件(反序列化)
// Student s1 = (Student) ois.readObject();
// Student s2 = (Student) ois.readObject();
ArrayList<Student> s = (ArrayList<Student>) ois.readObject();
//关闭
ois.close();
System.out.println("执行完毕");
// System.out.println(s1.toString());
// System.out.println(s2.toString());
System.out.println(s.toString());
}
}
字符编码
- ISO-8859-1收录除ASCII以外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
- UTF-8 针对Unicode码表的可变长字符串编码
- GB2312 简体中文
- GBK 简体中文、扩充
- BIG5 台湾、繁体中文
tips:当编码方式和解码方式不一致时,会出现乱码。