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

相关推荐
azhou的代码园3 分钟前
基于JAVA+SpringBoot+Vue的制造装备物联及生产管理ERP系统
java·spring boot·制造
波音彬要多做11 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
Swift社区19 分钟前
Excel 列名称转换问题 Swift 解答
开发语言·excel·swift
一道微光23 分钟前
Mac的M2芯片运行lightgbm报错,其他python包可用,x86_x64架构运行
开发语言·python·macos
矛取矛求27 分钟前
QT的前景与互联网岗位发展
开发语言·qt
Leventure_轩先生27 分钟前
[WASAPI]从Qt MultipleMedia来看WASAPI
开发语言·qt
向宇it42 分钟前
【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
开发语言·unity·c#·游戏引擎
wm104344 分钟前
java web springboot
java·spring boot·后端
smile-yan1 小时前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风1 小时前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java