IO
什么是流
- 概念:内存与存储设备之间传输数据的通道
- 水借助管道传输;数据借助流传输
流的分类
按方向【重点】:
- 输入流:将<存储设备>中的内容读入到<内存>中。
- 输出流:将<内存>中的内容写入到<存储设备>中。
按单位
- 字节流:以字节为单位,可以读写所有数据。
- 字符流:以字符为单位,只能读写文本数据。
按功能:
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础之上增强功能
字节流
字节流的父类(抽象类):
-
InputStream:字节输入流
- public int read(){}
- public int read(byte[] b){}
- public int read(byte[] b,int off,int len){}
-
OutputStream:字节输出流
-
public void write(int n){}
-
public void write(byte[] b){}
-
public void write(byte[] b, int off , int len){}
-
public static void main(String[] args) throws IOException { //创建FileInputStream,并指定文件路径 //FileInputStream fis = new FileInputStream("e:\\aaa.txt"); FileInputStream fis = new FileInputStream("e:\\IO流\\aaa.txt"); //2读取文件 //2.1单个字节来读取 效率不高 // int data=0; // while ((data=fis.read())!=-1){ // System.out.print((char)data); // } //2.2一次读取多个字节 byte[] buf=new byte[1024]; int count=0; while ((count=fis.read(buf))!=-1){ System.out.println(new String(buf,0,count)); } //3关闭 fis.close(); System.out.println(); System.out.println("执行完毕"); }
-
文件字节流
- FileInputStream:
- public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1
- FileOutputStream:
- public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流
字节缓冲流
缓冲流:BufferedInputStream/BufferedOutputStream
提高IO效率,减少访问磁盘的次数
数据存储在缓冲区中,flush是将缓存区的内容磁轭如文件中,也可以直接close
对象流
-
对象流:ObjectOutputStream/ObjectInputStream
/** * 使用ObjectInputStream实现反序列化(读取查构成对象) */ public class demo7 { public static void main(String[] args)throws Exception { //创建对象流 FileInputStream fis=new FileInputStream("e:\\IO流\\stu.bin"); ObjectInputStream ois=new ObjectInputStream(fis); //读取文件(反序列化) // Student s =(Student) ois.readObject(); // Student s2 =(Student) ois.readObject(); ArrayList<Student> list=(ArrayList<Student>)ois.readObject(); //关闭 ois.close(); System.out.println("执行完毕"); // System.out.println(s.toString()); // System.out.println(s2.toString()); System.out.println(list.toString()); }
/** * 使用ObjectOutputStream实现对象的序列化 * 注意事项: * (1)序列化类必须要实现Serializable接口 * (2)序列化类中对象属性要求实现Serializable接口 * (3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类 * (4)使用transient(瞬间的)修饰属性,这个属性不能序列化 * (5)静态属性不能被序列化 * (6)序列化多个对象,可以借助集合实现 */ public class demo6 { public static void main(String[] args) throws Exception { //创建对象流 FileOutputStream fos=new FileOutputStream("e:\\IO流\\stu.bin"); ObjectOutputStream oos=new ObjectOutputStream(fos); //序列化(写入操作) Student zhangsan=new Student("张三",20); Student lisi=new Student("李四",22); ArrayList<Student> list=new ArrayList<>(); list.add(zhangsan); list.add(lisi); oos.writeObject(list); //关闭 oos.close();; System.out.println("序列化完毕"); }
public class Student implements Serializable { /** * serialVersionUID:序列化版本号ID */ private static final long serialVersionUID=100L; private String name; private transient int age; public static String country="中国"; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Student(String name, int age) { this.name = name; this.age = age; }
-
增强了缓冲区功能
-
增强了读写8中基本数据类型和字符串功能
-
增强了读写对象的功能
- readObject()从流中读取一个对象
- writeObject(Object obj) 向流中写入一个对象
-
使用流传输对象的过程称为序列化,反序列化
/** * 使用ObjectOutputStream实现对象的序列化 * 注意事项: * (1)序列化类必须要实现Serializable接口 * (2)序列化类中对象属性要求实现Serializable接口 * (3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类 * (4)使用transient(瞬间的)修饰属性,这个属性不能序列化 * (5)静态属性不能被序列化 * (6)序列化多个对象,可以借助集合实现 */