• Java IO流:Buffered处理流、对象处理流


    目录

    介绍

    Buffered处理流:

    Buffered字符处理流(BufferedReader和BufferedWriter):

    BufferedReader:

    BufferedrWriter:

    案例:

     Buffered字节处理流(BufferedInputStream和BufferedOutputStream) :

    案例:

    对象处理流: 

    序列化和反序列化:

     ObjectOutputStream和ObjectInputStream:

    ObjectOutputStream(序列化):

     ObjectOutputStream(反序列化):

    对象处理流细节总结: 


    介绍

    在Java中的流,还分为字节流和处理流

    节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter

    2.处理流(也叫包装流)是“连接"在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter

    看下图: 

    节点流就是通过不同的方式去访问不同的数据源 ,比如文件就用文件流访问,数组就用数组流访问。

    而包装流就是将这些节点流进行整合包装,提供一个更为完整的读写功能体系。

    具体包装流是如何实现的,这就涉及到了一种涉及模式:拟修饰器设计模式。

    具体不好描述,看视频 BV15B4y1u7Rn P12节。

    Buffered处理流:

    Buffered字符处理流(BufferedReader和BufferedWriter):

    BufferedReader 和BufferedWriter属于字符流,是按照字符来读取数据的

    关闭时,只需要关闭外层流即可

    BufferedReader:

    可以引用所有的Read子类,包括文件、数组、管道等

    这里读取了story.txt文件,里面存放了之前使用输入输出流copy文件的代码

    1. package com.io.reader;
    2. import java.io.BufferedReader;
    3. import java.io.FileReader;
    4. /**
    5. * @author 华子
    6. * bufferedReader的使用
    7. */
    8. public class BufReader {
    9. public static void main(String[] args) throws Exception {
    10. String filePath = "e:\\story.txt";
    11. BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
    12. String line = " ";
    13. while((line = bufferedReader.readLine())!=null){
    14. System.out.println(line);
    15. }
    16. bufferedReader.close();
    17. }
    18. }

    这里还可以进行按行读取。

    运行结果:

    BufferedrWriter:

     它同样也可以引用Writer里的所有子类。

    1. package com.io.writer;
    2. import java.io.BufferedWriter;
    3. import java.io.FileWriter;
    4. /**
    5. * @author 华子
    6. * bufferedWriter的使用
    7. */
    8. public class BufWriter {
    9. public static void main(String[] args) throws Exception{
    10. String filePath = "e:\\ok.txt";
    11. BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
    12. bufferedWriter.write("Hello,郑仲华");
    13. bufferedWriter.newLine();
    14. bufferedWriter.write("Hello,郑仲华");
    15. bufferedWriter.newLine();
    16. bufferedWriter.write("Hello,郑仲华");
    17. bufferedWriter.newLine();
    18. bufferedWriter.close();
    19. }
    20. }

    很简单的代码,创建一个文件,写入数据 。(实现了换行nextLine)

    案例:

    BufferedReader和BufferedWriter拷贝文本文件:

    1. package com.io.writer;
    2. import java.io.*;
    3. /**
    4. * @author 华子
    5. * 使用BufferedReader和BufferedWtriter进行文件拷贝
    6. */
    7. public class BufCopy {
    8. public static void main(String[] args) throws Exception{
    9. String filePath01 = "e:\\story.txt";
    10. String filePath02 = "d:\\news.txt";
    11. String line = "";
    12. BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath01));
    13. BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath02));
    14. while ((line = bufferedReader.readLine())!=null){
    15. bufferedWriter.write(line);
    16. bufferedWriter.newLine();
    17. }
    18. System.out.println("拷贝成功...");
    19. if(bufferedReader!=null){
    20. bufferedReader.close();
    21. }
    22. if(bufferedWriter!=null){
    23. bufferedWriter.close();
    24. }
    25. }
    26. }

    因为这两兄弟属于字符流,无法读取二进制文件(图片,视频,音乐等) 

     Buffered字节处理流(BufferedInputStream和BufferedOutputStream) :

    用法和字符处理流类似。

    案例:

    使用BufferedInputStream和BufferedOutputStream拷贝二进制文件:

    1. package com.io.outputstream_;
    2. import java.io.BufferedInputStream;
    3. import java.io.BufferedOutputStream;
    4. import java.io.FileInputStream;
    5. import java.io.FileOutputStream;
    6. /**
    7. * @author 华子
    8. * BufferedInputStream和BufferedOutputStream拷贝二进制文件(图片、视频、音乐)
    9. * 字节流BufferedInputStream和BufferedOutputStream也可以用于操作文本文件
    10. */
    11. public class BufCopy02 {
    12. public static void main(String[] args) throws Exception{
    13. String srcFilePath = "e:\\demo.mp4";
    14. String destFilePath = "d:\\demo.mp4";
    15. int readLen = 0;
    16. byte[] buf = new byte[1024];
    17. BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
    18. BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFilePath));
    19. while((readLen = bufferedInputStream.read(buf))!=-1){
    20. bufferedOutputStream.write(buf,0,readLen);
    21. }
    22. System.out.println("拷贝成功...");
    23. if (bufferedInputStream != null){
    24. bufferedInputStream.close();
    25. }
    26. if (bufferedOutputStream != null){
    27. bufferedOutputStream.close();
    28. }
    29. }
    30. }

    对象处理流: 

    再看处理流之前,首先要搞懂两个概念。

    序列化和反序列化:

    1.序列化就是在保存数据时, 保存数据的值和数据类型

    2.反序列化就是在恢复数据时,恢复数据的值和数据类型

    3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该

    必须实现如下两个接口之一 :Serializable(是一个标记接口)或者Externalizable。

    大多数情况下都使用第一种接口,因为第二种接口需要实现方法。 

    大概图解: 

    接下来就是两种对象处理流:

     ObjectOutputStream和ObjectInputStream:

    ObjectOutputStream 提供序列化功能

     ObjectInputStream 提供反序列化功能

    看代码:

    ObjectOutputStream(序列化):

    1. package com.io.outputstream_;
    2. import java.io.FileOutputStream;
    3. import java.io.IOException;
    4. import java.io.ObjectOutputStream;
    5. /**
    6. * ObjectOutputStream 序列化数据
    7. */
    8. public class ObjOutputStream {
    9. public static void main(String[] args) throws IOException {
    10. String filePath = "e:\\data.dat";
    11. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
    12. // 序列化数据
    13. oos.writeInt(100);//这里实现了自动装箱 int -->Integer(实现了Serializable)
    14. oos.writeBoolean(true);//boolean-->Boolean(实现了Serializable)
    15. oos.writeChar('a');//char-->Char(实现了Serializable)
    16. oos.writeDouble(9.5);//double-->Double(实现了Serializable)
    17. oos.writeUTF("芝麻干");//String类型序列化
    18. oos.writeObject(new Dog("阿黄",3));
    19. oos.close();
    20. System.out.println("数据保存完毕(序列化形式)");
    21. }
    22. }

    写入数据(序列化数据)后,会生成一个.dat文件。

     ObjectOutputStream(反序列化):

    1. package com.io.inputSteam;
    2. import com.io.outputstream_.Dog;
    3. import java.io.FileInputStream;;
    4. import java.io.IOException;
    5. import java.io.ObjectInputStream;
    6. /**
    7. * @author 华子
    8. * ObjectInputStream实现数据反序列化
    9. */
    10. public class ObjInputStream {
    11. public static void main(String[] args) throws IOException, ClassNotFoundException {
    12. String filePath = "e:\\data.dat";
    13. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
    14. // 读取(反序列化)的顺序要和你保存的数据(序列化)的顺序一直
    15. System.out.println(ois.readInt());
    16. System.out.println(ois.readBoolean());
    17. System.out.println(ois.readChar());
    18. System.out.println(ois.readDouble());
    19. System.out.println(ois.readUTF());
    20. // dog的编译类型是Object,运行类型是Dog
    21. Object dog = ois.readObject();
    22. System.out.println("运行类型:"+dog.getClass());
    23. System.out.println(dog);
    24. // 如果要引用Dog的方法,需要向下转型
    25. Dog dog1 = (Dog)dog;
    26. System.out.println(dog1.getName());
    27. ois.close();
    28. }
    29. }

     读取数据(反序列化)

    运行结果:

    对象处理流细节总结: 

    对象处理流有很多细节,在这里总结一下:

    1)读写顺序要一致

    2)要求实现序列化或反序列化对象,需要实现Serializable

    3)序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性

    4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员

    5)序列化对象时,要求里面属性的类型也需要实现序列化接口

    6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

  • 相关阅读:
    JAVA计算机毕业设计音乐播放器Mybatis+源码+数据库+lw文档+系统+调试部署
    拼多多API接口详解:自动化获取商品信息的高效指南
    长沙驾考之路
    Transform介绍 - 源码分析(3)
    爱婴室主要股东再现减持:莫锐伟、王云亦是如此,业绩表现不理想
    ValueError: Unknown engine: openpyxl,pandas指定读取新版本execl
    记一次 .NET某工控自动化系统 崩溃分析
    人工智能轨道交通行业周刊-第15期(2022.9.19-9.25)
    PyTorch主要组成模块 | hook函数 | 正则化weight decay与Dropout | 标准化
    基于Spring MVC + Spring + MyBatis的【超市会员管理系统】
  • 原文地址:https://blog.csdn.net/qq_59212867/article/details/125484843