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

相关推荐
凤凰战士芭比Q1 分钟前
部署我的世界-java版服务器-frp内网穿透
java·服务器
小肖爱笑不爱笑2 分钟前
2025/11/5 IO流(字节流、字符流、字节缓冲流、字符缓冲流) 计算机存储规则(ASCII、GBK、Unicode)
java·开发语言·算法
CodeCraft Studio13 分钟前
PPT处理控件Aspose.Slides教程:使用Java将PowerPoint笔记导出为PDF
java·笔记·pdf·powerpoint·aspose·ppt转pdf·java将ppt导出pdf
手握风云-14 分钟前
Java 数据结构第二十八期:反射、枚举以及 lambda 表达式
java·开发语言
ᐇ95919 分钟前
Java Vector集合全面解析:线程安全的动态数组
java·开发语言
毕设源码-朱学姐29 分钟前
【开题答辩全过程】以 广州网红点打卡介绍网站为例,包含答辩的问题和答案
java·eclipse
程序定小飞1 小时前
基于springboot的web的音乐网站开发与设计
java·前端·数据库·vue.js·spring boot·后端·spring
Hello_WOAIAI1 小时前
2.4 python装饰器在 Web 框架和测试中的实战应用
开发语言·前端·python
搬山.摧城1 小时前
线程池和单例模式
开发语言·单例模式
百锦再1 小时前
第1章 Rust语言概述
java·开发语言·人工智能·python·rust·go·1024程序员节