一、字节打印输出流PrintStream

PrintStream 该流的作用是:将程序输出的内容,使用操作系统默认的编码集,进行字符处理 (好处:我们可以认识对应的文本内容)

  1. package exercise;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.PrintStream;
  7. public class MainEnter {
  8. public static void main(String[] args) {
  9. File file = new File("D:\\introduce.txt");
  10. if(!file.exists()) {
  11. try {
  12. file.createNewFile();
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. FileOutputStream fos = null;
  18. PrintStream ps = null;
  19. try {
  20. fos = new FileOutputStream(file);
  21. ps = new PrintStream(fos);
  22. ps.println("我是梁雨");
  23. } catch (FileNotFoundException e) {
  24. e.printStackTrace();
  25. }finally {
  26. try {
  27. ps.close();
  28. fos.close();
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34. }

二、对象流(ObjectInputStream | ObjectOutputStream)

对象流,可以认为是对数据流的进一步的封装,让我们可以使用对象化的方式来读写数据
JavaBean 的编程规范: 要求JavaBean 实现Serializable ,其目的是:为了让对象提供序列化 和 反序列化的能力
序列化:通过对象流 将对象数据 转换为 字节数据 的过程
反序列化:通过对象流 将字节数据 转换为 对象数据的过程 (反序列化也是一种创建对象的方式)
QQ截图20201014113515.png

2.1 对象输出流 ObjectOutputStream 的使用

ObjectOutputStream : 将对象数据 转换为 字节数据

    package com.woniuxy.java19.study.advance;
    import java.io.Serializable;
    public class OrderBean implements Serializable{
        /**
         * 为啥要加序列化ID?
         * 目的:是为保证 序列化和反序列过程中,对象的所对应的类 的版本  认为是一致的
         * 
         */
        private static final long serialVersionUID = 315682470257319334L;
        /**
         * 商品的名称
         */
        private String goodsName;
        /**
         * 数量
         */
        private int nums;
        private double price;
        public OrderBean(String goodsName, int nums, double price) {
            super();
            this.goodsName = goodsName;
            this.nums = nums;
            this.price = price;
        }
        public OrderBean() {
            super();
            // TODO Auto-generated constructor stub
        }
        public String getGoodsName() {
            return goodsName;
        }
        public void setGoodsName(String goodsName) {
            this.goodsName = goodsName;
        }
        public int getNums() {
            return nums;
        }
        public void setNums(int nums) {
            this.nums = nums;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        @Override
        public String toString() {
            return "OrderBean [goodsName=" + goodsName + ", nums=" + nums + ", price=" + price + "]";
        }
    }
    package com.woniuxy.java19.study.advance;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    public class ObjectOutputStreamStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //定义多个对象
            OrderBean order01 = new OrderBean("卫衣", 20, 200.0);
            OrderBean order02 = new OrderBean("裙子", 31, 600.0);
            //d:\\order.txt
            File file = new File("D:\\order.txt");
            ObjectOutputStream oos = null;
            FileOutputStream fos = null;
            try {
                if(!file.exists()) {
                    file.createNewFile();
                }
                //创建流
                fos = new FileOutputStream(file);
                oos = new ObjectOutputStream(fos);
                //操作流
                oos.writeObject(order01);
                oos.writeObject(order02);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                //关闭流
                try {
                    oos.close();
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

2.2 ObjectInputStream 对象输入流

ObjectInputStream:将 字节数据 转换为 对象数据

    package com.woniuxy.java19.study.advance;
    import java.io.EOFException;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    /**
     * 对象输入流
     * @author Administrator
     *
     */
    public class ObjectInputStreamStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            File file = new File("D:\\order.txt");
            ObjectInputStream ois = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(file);
                ois = new ObjectInputStream(fis);
                //操作流
                while(true) {
                    Object obj = ois.readObject();
                    if(obj instanceof OrderBean) {
                        OrderBean order = (OrderBean)obj;
                        System.out.println(order);
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
                if(e instanceof EOFException) {
                    System.out.println("数据读取完毕!");
                }else {
                    e.printStackTrace();
                }
            }finally {
                try {
                    ois.close();
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

2.3 实现Serializable接口的目的

原因:(对象数据库的使用,网络数据传输过程)使用对象流传输数据时,要求:对象数据 可以和 字节数据 相互转换。
实现了Serializable接口的类可以被序列化输出,但并非该类的任何内容都能被序列化。在类中,属性(包括基本数据类型、数组、对其他对象的引用)以及类名可以被序列化,而static属性、方法、加了transient修饰符的属性则不能被序列化。

2.4 提供Serializable ID属性的目的

目的:是为保证 序列化和反序列过程中,对象的所对应的类的版本 认为是一致的
如果不加,那么每次修改类,编译器都会自动生成一个新的Serializable ID,这样反序列化时,就会出问题

2.5 transient 关键字

transient 表示某一个属性,无需参与序列化

    package com.woniuxy.java19.study.advance;
    import java.io.Serializable;
    public class OrderBean implements Serializable{
        /**
         * 为啥要加序列化ID?
         * 目的:是为保证 序列化和反序列过程中,对象的所对应的类 的版本  认为是一致的
         * 
         */
        private static final long serialVersionUID = 315682470257319334L;
        /**
         * 商品的名称
         */
        private String goodsName;
        /**
         * 数量
         */
        private int nums;
        /**
         * 单价
         * transient 关键字(表示:该属性无需参与序列化)
         */
        private transient double price;
        public OrderBean(String goodsName, int nums, double price) {
            super();
            this.goodsName = goodsName;
            this.nums = nums;
            this.price = price;
        }
        public OrderBean() {
            super();
            // TODO Auto-generated constructor stub
        }
        public String getGoodsName() {
            return goodsName;
        }
        public void setGoodsName(String goodsName) {
            this.goodsName = goodsName;
        }
        public int getNums() {
            return nums;
        }
        public void setNums(int nums) {
            this.nums = nums;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        @Override
        public String toString() {
            return "OrderBean [goodsName=" + goodsName + ", nums=" + nums + ", price=" + price + "]";
        }
    }

三、字符流

字符流操作的以字符(2个字节)为单位进行 数据的读写
字符流用于处理文本文件。所有字符流都继承于抽象类Reader和Writer两个父类。
图片1.png

图片2.png

分类

低级字符流,高级字符流

3.1 低级字符流

操作文件的:FileReader FileWrite (*)
操作线程通讯的:PipedReader PipedWrite
操作内存字符串的:StringReader StringWriter
操作内存字符数组的:CharArrayReader CharArrayWrite

FileWrite 的使用

将程序中的数据,使用字符的方式 写入到外部文件中去

    package com.woniuxy.java19.study.lower;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    /**
     * 文件输出字符流
     * @author Administrator
     *
     */
    public class FileWriteStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //定义文件对象
            File file = new File("d:\\students.txt");
            //创建流
            FileWriter write = null;
            try {
                if(!file.exists()) {
                    file.createNewFile();
                }
                //操作流(true 表示操作方式为:追加模式)
                write = new FileWriter(file,true);
                String str = "台湾是中国的!!!";
                write.write(str);
                String str02 = "钓鱼岛也是中国的!!!";
                char[] arr = str02.toCharArray();
                write.write(arr);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                //关闭流
                try {
                    write.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

FileReader的使用

将外部文件的内容,使用字符的方式 读取到程序中来

    package com.woniuxy.java19.study.lower;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Arrays;
    public class FileReaderStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //定义文件对象
            File file = new File("d:\\students.txt");
            FileReader reader = null;
            try {
                //实例化
                reader = new FileReader(file);
                char[] data = new char[1024];
                //操作流
                while(reader.read(data) != -1) {
                    //以字符数组的方式输出
    //                System.out.println(Arrays.toString(data));
                    //字符串的方式输出内容
                    System.out.println(new String(data));
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

3.2 高级字符流

高级流:对低级流的包装 提供新的能力:缓冲,转换,打印输出

3.2.1 分类

缓冲流:包括BufferedReader和BufferedWriter类,利用缓冲区来提高读写数据的效率。
转换流:用于字节数据到字符数据之间的转换,包括InputStreamReader和OutputStreamWriter
打印输出流:包括PrintWriter类,允许将基本类型数据打印输出到字符串流中,PrintWriter带有带自动刷新(Flush)功能。

3.2.2 缓冲流 BufferedReader BufferedWriter

    package com.woniuxy.java19.study.advance;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    public class BufferedReaderStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            File file = new File("D:\\index.txt");
            BufferedReader reader = null;
            //字节转换字符流
            InputStreamReader isr = null;
            FileInputStream fis = null;
            try {
                //创建流
                fis = new FileInputStream(file);
                isr = new InputStreamReader(fis, "GBK");
                reader = new BufferedReader(isr);
                String content = "";
                //操作流
                while((content = reader.readLine()) != null) {
                    System.out.println(content);
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                try {
                    reader.close();
                    isr.close();
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    package com.woniuxy.java19.study.advance;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    public class BufferedWriteStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            File file = new File("D:\\user.txt");
            OutputStreamWriter osw = null;
            BufferedWriter writer  = null;
            FileOutputStream fos = null;
            try {
                if(!file.exists()) {
                    file.createNewFile();
                }
                //建立流
                fos = new FileOutputStream(file);
                osw = new OutputStreamWriter(fos, "GBK");
                writer = new BufferedWriter(osw);
                //操作流
                writer.write("台湾是中国的!!!");
                //换行
                writer.newLine();
                String str = "我是老婆的!!!";
                char[] data = str.toCharArray();
                writer.write(data);
                //刷新流
                writer.flush();
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                try {
                    writer.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

3.3.3 字符打印输出流PrintWrite

前面讲过字节打印输出流 PrintStream (它的作用:将字节 按照操作系统默认的编码 进行数据的读写)
PrintWrite 和 PrintStream 在功能上是一样的。区别:在于PrintWrite 可以设置其他字符集

    package com.woniuxy.java19.study.advance;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    public class PrintWriterStudy {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //先定义一个文件对象
            File file = new File("d:\\movie\\lyf.txt");
            PrintWriter writer = null;
            OutputStreamWriter osw = null;
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
                //PrintWriter可以 借助OutputStreamWriter 进行编码集的设置
                osw = new OutputStreamWriter(fos, "GBK");
                writer = new PrintWriter(osw);
                writer.println("花木兰");
                writer.println("仙剑奇侠传");
                writer.println("神雕侠侣");
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                writer.close();
            }
        }
    }

四、流的使用规则

1、如果数据源是文件,对于字节流,使用FileInputStream和FileOutputStream;对于字符流,使用FileReader和 FileWriter。
2、如果数据源是字节数组byte[],则使用ByteArrayInputStream和ByteArrayOutputStream。
3、如果数据源是字符数组Char[],则使用CharArrayReader和CharArrayWriter。
4、如果数据源是String对象,对于字节流,则使用StringBufferInputStream和StringBufferOuputStream;对于字符流,则使用StringReader和StringWriter。
5、如果数据源是网络数据流,对于字节流,使用InputStream和OutputStream;对于字符流,使用Reader和Writer。