Java高级流

高级流

java将IO分为了两类

  • 节点流:又称为"低级流"
    • 特点:直接链接程序与另一端的"管道",是真实读写数据的流
    • IO一定是建立在节点流的基础上进行的。
    • 文件流就是典型的节点流(低级流)
  • 处理流:又称为"高级流"
    • 特点:不能独立存在,必须链接在其他流上
    • 目的:当数据经过当前高级流时可以对数据进行某种加工操作,来简化我们的同等操作
    • 实际开发中我们经常"串联"一组高级流最终到某个低级流上,使读写数据以流水线式的加工处理完成。这一操作也被称为使"流的链接"。流链接也是JAVA IO的精髓所在。
缓冲流

java.io.BufferedInputStreamBufferedOutputStream

功能

在流链接中的作用:加快读写效率

通常缓冲是最终链接在低级流上的流

构造器
  • 缓冲字节输出流

    java 复制代码
    BufferedOutputStream(OutputStream out)
    实例化一个缓冲字节输出流并链接在指定的字节输出流上。默认缓冲区大小8kb(内部维护的byte[] buf数组长度8192)
    
    BufferedOutputStream(OutputStream out,int size)
    实例化一个指定缓冲区大小的缓冲字节输出流并链接在指定的字节输出流上。
  • 缓冲字节输入流

    java 复制代码
    BufferedInputStream(InputStream in)
    实例化一个缓冲字节输入流并链接在指定的字节输入流上。默认缓冲区大小8kb(内部维护的byte[] buf数组长度8192)
    
    BufferedInputStream(InputStream in,int size)
    实例化一个指定缓冲区大小的缓冲字节输入流并链接在指定的字节输入流上。    
java 复制代码
package io;

import java.io.*;

/**
 * 使用缓冲流完成文件复制操作
 */
public class CopyDemo3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("image.png");
        BufferedInputStream bis = new BufferedInputStream(fis);

        FileOutputStream fos = new FileOutputStream("image_cp3.png");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int d;
        long start = System.currentTimeMillis();
        while((d=bis.read())!= -1){
            bos.write(d);
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕!耗时:"+(end-start)+"ms");
        bis.close();
        bos.close();

    }
}
原理

内部定义了一个属性byte buf[]。它等同于我们之前练习复制案例时的块写操作。

并且默认创建时,该buf数组的长度为8192(8kb)长度。

缓冲流在读写数据时总是以块读写数据(默认是8kb)来保证读写效率的

缓冲流提供了多种构造器,可以自行指定缓冲区大小。

写缓冲问题

由于缓冲输出流会将写出的数据装满内部缓冲区(默认8kb的字节数组)后才会进行一次真实的写出操作。当我们的数据不足时,如果想要及时写出数据,可以调用缓冲流的flush()方法,强制将缓冲区中已经缓存的数据写出一次。

java 复制代码
package io;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 缓冲输出流的写缓冲问题
 */
public class BosFlushDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("bos.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        String line = "super idol的笑容都没你的甜~";
        byte[] data = line.getBytes(StandardCharsets.UTF_8);
        bos.write(data);
        /*
            void flush()
            强制将缓冲流的缓冲取(内部维护的字节数组)中已经缓存的字节一次性写出
         */
//        bos.flush();
        System.out.println("写出完毕!");
        bos.close();//缓冲输出流的close()方法内部会自动调用一次flush()方法确保数据写出
    }
}
flush的传递

flush()方法是被定义在java.io.Flushable中。而字节输出流的超类java.io.OutputStream实现了

该接口,这意味着所有的字节输出流都有flush方法。而除了缓冲流之外的高级流的flush方法作用就是调用它链接的流的flush方法将该动作传递下去。最终传递给缓冲流来清空缓冲区。

对象流

java.io.ObjectInputStreamObjectOutputStream

作用
  • 对象输出流:将我们的java对象进行序列化
  • 对象输入流:将java对象进行反序列化
序列化

将一个对象转换为一组可被传输或保存的字节。这组字节中除了包含对象本身的数据外,还会包含结构信息。

序列化的意义

实际开发中,我们通常会将对象

  • 写入磁盘,进行长久保存
  • 在网络间两台计算机中的java间进行传输

无论是保存在磁盘中还是传输,都需要将对象转换为字节后才可以进行。

对象输出流的序列化操作
java 复制代码
void writeObject(Object obj)
将给定的对象转换为一组可保存或传输的字节然后通过其链接的流将字节写出
例:
java 复制代码
package io;

import java.io.*;

/**
 * 对象流
 * 使用对象输出流完成对象序列化操作并最终保存到文件person.obj中
 */
public class OOSDemo {
    public static void main(String[] args) throws IOException {
        String name = "张三";
        int age = 18;
        String gender = "女";
        String[] otherInfo = {"黑","壮实","java技术好","来自鄂尔多斯"};
        Person p = new Person(name,age,gender,otherInfo);
        FileOutputStream fos = new FileOutputStream("person.obj");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        /*
            对象输出流提供的序列化对象方法:
            void writeObject(Object obj)
            将给定的对象转换为一组可保存或传输的字节然后通过其链接的流将字节写出

            序列化对象时要求该对象对应的类必须实现接口:java.io.Serializable
            如果写出的对象对应的类没有实现该接口,那么writeObject会抛出下面异常
            java.io.NotSerializableException

         */
        oos.writeObject(p);
        System.out.println("对象写出完毕");
        oos.close();
    }
}
序列化要求

对象输出流要求写出的对象必须实现接口:java.io.Serializable

上述案例中我们看到,如果写出的对象Person没有实现java.io.Serializable时会抛出异常:

java.io.NotSerializableException

相关推荐
码老白几秒前
【老白学 Java】Warshipv2.0(二)
java·网络
苹果酱05671 分钟前
前端面试vue篇:Vue2 和 Vue3 在设计和性能上有显著区别
java·spring boot·毕业设计·layui·课程设计
LKID体11 分钟前
Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作(三)
开发语言·python·neo4j
小屁孩大帅-杨一凡13 分钟前
Python-flet实现个人视频播放器
开发语言·python·音视频
万琛13 分钟前
【java-Neo4j 5开发入门篇】-最新Java开发Neo4j
java·neo4j
算家云15 分钟前
快速识别模型:simple_ocr,部署教程
开发语言·人工智能·python·ocr·数字识别·检测模型·英文符号识别
Thomas_Cai26 分钟前
Python后端flask框架接收zip压缩包方法
开发语言·python·flask
霍先生的虚拟宇宙网络29 分钟前
webp 网页如何录屏?
开发语言·前端·javascript
温吞-ing31 分钟前
第十章JavaScript的应用
开发语言·javascript·ecmascript