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文件的代码

package com.io.reader;


import java.io.BufferedReader;
import java.io.FileReader;

/**
 * @author 华子
 * bufferedReader的使用
 */
public class BufReader {
    public static void main(String[] args) throws Exception {
        String filePath = "e:\\story.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String  line = " ";
        while((line = bufferedReader.readLine())!=null){
            System.out.println(line);
        }
        bufferedReader.close();
    }

}

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

运行结果:

BufferedrWriter:

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

package com.io.writer;

import java.io.BufferedWriter;
import java.io.FileWriter;

/**
 * @author 华子
 * bufferedWriter的使用
 */
public class BufWriter {
    public static void main(String[] args) throws Exception{
        String filePath = "e:\\ok.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
        bufferedWriter.write("Hello,郑仲华");
        bufferedWriter.newLine();
        bufferedWriter.write("Hello,郑仲华");
        bufferedWriter.newLine();
        bufferedWriter.write("Hello,郑仲华");
        bufferedWriter.newLine();
        bufferedWriter.close();
    }
}

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

案例:

BufferedReader和BufferedWriter拷贝文本文件:

package com.io.writer;

import java.io.*;

/**
 * @author 华子
 * 使用BufferedReader和BufferedWtriter进行文件拷贝
 */
public class BufCopy {
    public static void main(String[] args) throws Exception{
        String filePath01 = "e:\\story.txt";
        String filePath02 = "d:\\news.txt";
        String line = "";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath01));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath02));
        while ((line = bufferedReader.readLine())!=null){
            bufferedWriter.write(line);
            bufferedWriter.newLine();
        }
        System.out.println("拷贝成功...");
        if(bufferedReader!=null){
            bufferedReader.close();
        }
        if(bufferedWriter!=null){
            bufferedWriter.close();
        }
    }
}

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

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

用法和字符处理流类似。

案例:

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

package com.io.outputstream_;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * @author 华子
 * BufferedInputStream和BufferedOutputStream拷贝二进制文件(图片、视频、音乐)
 * 字节流BufferedInputStream和BufferedOutputStream也可以用于操作文本文件
 */
public class BufCopy02 {
    public static void main(String[] args) throws Exception{
        String srcFilePath = "e:\\demo.mp4";
        String destFilePath = "d:\\demo.mp4";
        int readLen = 0;
        byte[] buf = new byte[1024];
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFilePath));
        while((readLen = bufferedInputStream.read(buf))!=-1){
            bufferedOutputStream.write(buf,0,readLen);
        }
        System.out.println("拷贝成功...");
        if (bufferedInputStream != null){
            bufferedInputStream.close();
        }
        if (bufferedOutputStream != null){
            bufferedOutputStream.close();
        }
    }
}

对象处理流: 

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

序列化和反序列化:

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

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

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

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

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

大概图解: 

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

 ObjectOutputStream和ObjectInputStream:

ObjectOutputStream 提供序列化功能

 ObjectInputStream 提供反序列化功能

看代码:

ObjectOutputStream(序列化):

package com.io.outputstream_;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * ObjectOutputStream 序列化数据
 */
public class ObjOutputStream {
    public static void main(String[] args) throws IOException {
        String filePath = "e:\\data.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//        序列化数据
        oos.writeInt(100);//这里实现了自动装箱 int -->Integer(实现了Serializable)
        oos.writeBoolean(true);//boolean-->Boolean(实现了Serializable)
        oos.writeChar('a');//char-->Char(实现了Serializable)
        oos.writeDouble(9.5);//double-->Double(实现了Serializable)
        oos.writeUTF("芝麻干");//String类型序列化
        oos.writeObject(new Dog("阿黄",3));
        oos.close();
        System.out.println("数据保存完毕(序列化形式)");
    }
}

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

 ObjectOutputStream(反序列化):

package com.io.inputSteam;

import com.io.outputstream_.Dog;

import java.io.FileInputStream;;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * @author 华子
 * ObjectInputStream实现数据反序列化
 */
public class ObjInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String filePath = "e:\\data.dat";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
//        读取(反序列化)的顺序要和你保存的数据(序列化)的顺序一直
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
//        dog的编译类型是Object,运行类型是Dog
        Object dog = ois.readObject();
        System.out.println("运行类型:"+dog.getClass());
        System.out.println(dog);
//        如果要引用Dog的方法,需要向下转型
        Dog dog1 = (Dog)dog;
        System.out.println(dog1.getName());
        ois.close();
    }

}

 读取数据(反序列化)

运行结果:

对象处理流细节总结: 

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

1)读写顺序要一致

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

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

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

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

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝麻干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值