Java--流的定义及分类、字节节点流、字节过滤流(缓冲流、对象流)

一、流的定义

  定义:内存与存储设备之间传输数据的通道

        程序是在内存中运行的,文件在硬盘上,如果想要读取硬盘上的文件,需要在内存和硬盘之间建立一个通道

二、流的分类

  2.1按方向分:

    输入流:将<存储设备>中的内容读入到<内存>中

    输出流:将<内存>中的内容写入到<存储设备>中

  2.2按单位分:

    字节流:以字节为单位,可以读写所有数据

    字符流:以字符为单位,只能读写文本数据

  2.3按功能分:

    节点流:具有实际传输数据的读写功能

    过滤流:在节点流的基础之上增强功能

三、字节节点流

  字节流(抽象类):

    InputStream:字节输入流(从存储设备读到内存)

      pubic int read(){};//从输入流中读取数据

      public int read(byte[] b){};//从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中

      public int read(byte[] b,int off,int len){};//将输入流中最多len个数据字节读入byte数组

    OutputStream:字节输出流(从内存保存到存储设备)

      public int write(int n){}//将指定的字节写入此输出流

      public int write(byte[] b){}//将b.length个字节从指定的byte数组写入此输出流

      public int write(byte[] b,int off,int len){}//将写指定byte数组中从off位置开始的len个字节写入此输出流

  文件字节流:

    FileInputStream:public int read(byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。

    FileOutputStream: public void write(byte[] b)//一次写多个字节,将b数组中所有字节,写入输出流

  案例:文件字节输入输出流的使用

package com.monv.chapter15;

import java.io.FileInputStream;

/**
 * 演示FileInputStream的使用
 * 文件字节输入流
 * @author Monv
 *
 */
public class Demo1 {
    public static void main(String[] args) throws Exception {
        //1.创建FileInputStream,并指定文件路径
        FileInputStream fis = new FileInputStream("D:\\aaa.Txt");
        //2.读取文件
        //2.1 单个字节读取  将读取的每个字节赋值给Data并输出  =-1的时候 说明读完了 跳出循环
//        int data =0;
//        while ((data = fis.read()) !=-1) {
//            System.out.println((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("读取完毕");
    }
}
--------------------------------------------------------------------
package com.monv.chapter15;

import java.io.FileOutputStream;

/**
 * 演示文件字节输出流的使用
 * FileOutputStream
 * @author Monv
 *
 */
public class Demo2 {
    public static void main(String[] args) throws Exception{
        //1创建文件字节输出流对象 第二个参数 为true 表示 在原有文件上追加内容 
        FileOutputStream fos = new FileOutputStream("D:\\bbb.txt",true);
        //2.写入文件
//        fos.write(97);
//        fos.write('b');
//        fos.write('c');
        String str = "HelloWorld";
        fos.write(str.getBytes());
        //3.关闭
        fos.close();
        System.out.println("执行完毕");
    }
}
---------------------------------------------------------
package com.monv.chapter15;

import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * 使用文件字节流来实现文件的复制
 * @author Monv
 *
 */
public class Demo3 {
    public static void main(String[] args) throws Exception {
        //1 创建流
        //1.1 创建文件字节输入流
        FileInputStream fis = new FileInputStream("D:\\111.jpg");
        //1.2 创建文件字节输出流
        FileOutputStream fos = new FileOutputStream("D:\\222.jpg");
        //2 一边读 一遍写
        byte[] buf = new byte[1024];
        int count = 0;
        while((count = fis.read(buf)) !=-1) {
            fos.write(buf,0,count);//不能保证每次读取1024的大小 所以把count传进来 读多少写多少
        }
        //3.关闭
        fis.close();
        fos.close();
        
        System.out.println("执行完毕");
    }
}

 

四、字节过滤流:

  缓冲流:BufferedOutputStream/BufferedInputStream

    提高IO效率,减少访问磁盘的次数;数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。

  对象流:ObjectOutputStream/ObjectInputStream

    增强了缓冲区功能

    增强了读写8种基本数据类型和字符串功能

    增强了读写对象的功能:readObject() 从流中读取一个对象

               writeObject(Object obj) 向流中写入一个对象

    注:使用流传输对象的过程成为序列化(写入文件)、反序列化(读取文件)

    对象序列化注意事项

    1)、序列化类必须实现Serializable接口

    2)、序列化类中对象属性要求实现Serializable接口

    3)、序列化版本号ID serialVersionUID ,保证序列化的类和反序列化的类是同一个类

    4)、使用transient(瞬间的)修饰属性,这个属性就不能序列化

    5)、静态属性也是不能序列化的(不能保存到硬盘上)

    6)、序列化多个对象的时候 可以借助集合来实现

    案例1:使用缓冲流来读写数据

package com.monv.chapter15;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

/**
 * 使用字节缓冲流读取
 * BufferedInputStream
 * @author Monv
 *
 */
public class Demo4 {
    public static void main(String[] args) throws Exception {
        //1.创建BufferedInputStream
        FileInputStream fis = new FileInputStream("D:\\aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        //2.读取
//        int data = 0;
//        while ((data = bis.read())!= -1 ) {
//            System.out.print((char)data);
//        }
        int count =0;
        byte[] buf = new byte[1024];
        while ((count = bis.read(buf)) != -1) {
            System.out.print(new String(buf,0,count));
        }
        //3.关闭 只关闭缓冲流就行了 内部 会把fis关掉
        bis.close();
        System.out.println("执行完毕");
        
    }
}
--------------------------------------------------
package com.monv.chapter15;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

/**
 * 使用字节缓冲流写入数据
 * @author Monv
 *
 */
public class Demo5 {
    public static void main(String[] args) throws Exception{
        //1.创建字节流 及 字节缓冲流
        FileOutputStream fos = new FileOutputStream("D:\\001.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //2.写入文件
        for(int i =0;i<10;i++) {
            bos.write("HelloWorld ".getBytes());//写入8k缓冲区
            bos.flush();//刷新到硬盘
        }
        //关闭(内部会调用flush)
        bos.close();
    }
}

    案例2:使用对象流来读写数据

--------------------学生类--------------------------
package com.monv.chapter15;
/**
 * 要想这个对象可以序列化 必须 要实现 Serializable接口
 */
import java.io.Serializable;

public class Student implements Serializable{
    /**
     * serialVersionUID:序列化版本号ID,保证序列化的类和反序列化的类是同一个类
     */
    private static final long serialVersionUID = 100L;
    private String name;
    private transient int age;
    private static String  country ="中国";
    
    
    public Student() {
        // TODO Auto-generated constructor stub
    }

    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    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 + "]";
    }
    
}
------------------------序列化操作-------------------------------
package com.monv.chapter15;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

/**
 * 使用ObjectOutputStream实现对象的序列化
 * 注意事项:
 * (1)序列化类必须实现Serializable接口
 * (2)序列化类中对象属性要求实现Serializable接口
 * (3)序列化版本号ID serialVersionUID ,保证序列化的类和反序列化的类是同一个类
 * (4)使用transient(瞬间的)修饰属性,这个属性就不能序列化
 * (5)静态属性也是不能序列化的(不能保存到硬盘上)
 * (6)序列化多个对象的时候 可以借助集合来实现
 * @author Monv
 *
 */
public class Demo6 {
    public static void main(String[] args) throws Exception{
        //1.创建对象流  需要借助文件流
        FileOutputStream fos = new FileOutputStream("D:\\Stu.bin"); 
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //2.序列化 就是写入操作
        Student s1 = new Student("张三",20);
        Student s2 = new Student("李四",21);
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        oos.writeObject(list);
//        oos.writeObject(s1);
//        oos.writeObject(s2);
        //3关闭
        oos.close();
        System.out.println("序列化完毕");
    }
}
-----------------------反序列化操作------------------------------
package com.monv.chapter15;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;


/**
 * 使用ObjectInputStream实现反序列化(读取重构生成对象)
 * @author Monv
 *
 */
public class Demo7 {
    public static void main(String[] args) throws Exception{
        //1.创建对象
        FileInputStream fis = new FileInputStream("D:\\\\Stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        //2.读取对象 只写入了一个对象 不能读多个  读完一次再读就会报错
//        Student  s1 = (Student)ois.readObject();
//        Student  s2 = (Student)ois.readObject();//只写入了一个对象的情况下 不能读多次 第二次读会报错(java.io.EOFException 读取到文件尾部的标志)
        ArrayList<Student> list = (ArrayList<Student>)ois.readObject();
        //3.关闭
        ois.close();
        System.out.println("反序列化执行完毕");
//        System.out.println(s1.toString());
//        System.out.println(s2.toString());
        System.out.println(list.toString());
    }
}
-------------------------------------------------------------

 

     

 

posted @ 2021-01-23 18:56  改Bug的小魔女  阅读(642)  评论(0编辑  收藏  举报