高级流

流连接示意图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L8ArsiJ5-1664773521949)(image-20210528141614174.png)]

缓冲流

java.io.BufferedOutputStream和BufferedInputStream.

缓冲流是一对高级流,作用是提高读写数据的效率.

缓冲流内部有一个字节数组,默认长度是8K.缓冲流读写数据时一定是将数据的读写方式转换为块读写来保证读写效率.

使用缓冲流完成文件复制操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yMZNufVA-1664773521952)(image-20210427164418295.png)]

package io;import java.io.*;/*** java将流分为节点流与处理流两类* 节点流:也称为低级流,是真实连接程序与另一端的"管道",负责实际读写数据的流。*       读写一定是建立在节点流的基础上进行的。*       节点流好比家里的"自来水管"。连接我们的家庭与自来水厂,负责搬运水。* 处理流:也称为高级流,不能独立存在,必须连接在其他流上,目的是当数据经过当前流时*       对其进行某种加工处理,简化我们对数据的同等操作。*       高级流好比家里常见的对水做加工的设备,比如"净水器","热水器"。*       有了它们我们就不必再自己对水进行加工了。* 实际开发中我们经常会串联一组高级流最终连接到低级流上,在读写操作时以流水线式的加工* 完成复杂IO操作。这个过程也称为"流的连接"。** 缓冲流,是一对高级流,作用是加快读写效率。* java.io.BufferedInputStream和java.io.BufferedOutputStream**/
public class CopyDemo3 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("ppt.pptx");BufferedInputStream bis = new BufferedInputStream(fis);FileOutputStream fos = new FileOutputStream("ppt_cp.pptx");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();}
}
缓冲输出流写出数据时的缓冲区问题

通过缓冲流写出的数据会被临时存入缓冲流内部的字节数组,直到数组存满数据才会真实写出一次

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 BOS_FlushDemo {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("bos.txt");BufferedOutputStream bos = new BufferedOutputStream(fos);String line = "奥里给!";byte[] data = line.getBytes(StandardCharsets.UTF_8);bos.write(data);System.out.println("写出完毕!");/*缓冲流的flush方法用于强制将缓冲区中已经缓存的数据一次性写出。注:该方法实际上实在字节输出流的超类OutputStream上定义的,并非只有缓冲输出流有这个方法。但是实际上只有缓冲输出流的该方法有实际意义,其他的流实现该方法的目的仅仅是为了在流连接过程中传递flush动作给缓冲输出流。*/bos.flush();//冲bos.close();}
}

对象流

java.io.ObjectOutputStream和ObjectInputSteam

对象流是一对高级流,在流连接中的作用是进行对象的序列化与反序列化。

对象序列化:将一个java对象按照其结构转换为一组字节的过程

对象反序列化:将一组字节还原为java对象(前提是这组字节是一个对象序列化得到的字节)

对象序列化的流连接操作原理图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-flU6cwJt-1664773521953)(image-20210528162433406.png)]

package io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;/*** 对象流(是一对高级流)* java.io.ObjectInputStream和ObjectOutputStream* 对象流在流连接中的作用是进行对象的序列化与反序列化* 其中对象输出流负责对象序列化。对象输入流负责对象反序列化** 所谓对象序列化:* 将写出的对象按照其结构转换为一组字节的过程。*/
public class OOSDemo {public static void main(String[] args) throws IOException {String name = "苍老师";int age = 55;String gender = "男";String[] otherInfo = {"摄影技术一流","喜欢拍片儿","是一名技术老师"};//将该Person对象写入文件person.obj中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.NotSerializableException: io.Person注:冒号后面的io.Person是指序列化的就是这个类的实例出现的错误原因:对象输出流在进行序列化对象时,要求该对象所属的类必须实现接口:java.io.Serializable接口并且该类中所有引用类型属性也必须实现该接口,否则会抛出上述异常。*/oos.writeObject(p);System.out.println("写出完毕!");oos.close();}
}
对象反序列化
package io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;/*** 使用对象输入流完成对象的反序列化*/
public class OISDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {//从person.obj文件中将对象反序列化回来FileInputStream fis = new FileInputStream("person.obj");ObjectInputStream ois = new ObjectInputStream(fis);/*Object readObject()该方法会进行对象的反序列化,如果对象流通过其连接的流读取的字节分析并非是一个java对象时,会抛出异常:ClassNotFoundException*/Person p = (Person)ois.readObject();System.out.println(p);}
}

需要进行序列化的类必须实现接口:java.io.Serializable 实现序列化接口后最好主动定义序列化版本号这个常量。 这样一来对象序列化时就不会根据类的结构生成一个版本号,而是使用该固定值。 那么反序列化时,只要还原的对象和当前类的版本号一致就可以进行还原。

transient关键字可以修饰属性,用于在进行对象序列化时忽略不必要的属性,达到对象瘦身的目的

package io;import java.io.Serializable;
import java.util.Arrays;/*** 使用当前类实例测试对象流的读写操作*/
public class Person implements Serializable {public static final long serialVersionUID = 1L;private String name;//姓名private int age;//年龄private String gender;//性别private String[] otherInfo;//其他信息public Person(String name, int age, String gender, String[] otherInfo) {this.name = name;this.age = age;this.gender = gender;this.otherInfo = otherInfo;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String[] getOtherInfo() {return otherInfo;}public void setOtherInfo(String[] otherInfo) {this.otherInfo = otherInfo;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +", otherInfo=" + Arrays.toString(otherInfo) +'}';}
}

字符流

  • java将流按照读写单位划分为字节流与字符流.
  • java.io.InputStream和OutputStream是所有字节流的超类
  • 而java.io.Reader和Writer则是所有字符流的超类,它们和字节流的超类是平级关系.
  • Reader和Writer是两个抽象类,里面规定了所有字符流都必须具备的读写字符的相关方法.
  • 字符流最小读写单位为字符(char),但是底层实际还是读写字节,只是字符与字节的转换工作由字符流完成.

转换流

java.io.InputStreamReader和OutputStreamWriter

它们是字符流非常常用的一对实现类同时也是一对高级流,实际开发中我们不直接操作它们,但是它们在流连接中是非常重要的一环.

使用转换输出流向文件中写入文本数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLyP1wWP-1664773521955)(image-20220207175957369.png)]

package io;import java.io.*;
import java.nio.charset.StandardCharsets;/*** JAVA IO将流按照读写数据的单位将流分为了两类:字节流与字符流* java.io.InputStream和OutputStream这两个超类是所有【字节流】的超类* java.io.Reader和Writer这两个是所有【字符流】的超类* 这两对超类之间是没有继承关系的,属于平级的。** 字符流是以字符为最小单位(char)读写数据的。* 注:底层实际还是读写字节,只不过字符与字节的转换由字符流自动完成了。* 由于字符流最小读写单位为字符,因此字符流【只适合读写文本数据】** 转换流(是一对高级流,同时是一对字符流)* 作用:* 1:衔接字节流与其他字符流* 2:将字符与字节相互转换* 实际开发中我们不会直接使用这一对流,但是在流连接中它是重要的一环。*/
public class OSWDemo {public static void main(String[] args) throws IOException {/*使用这一对流演示转换流的读写字符方法java.io.Writer所有字符输出流的超类上,定义了写出字符的相关方法void write(int d)写出一个字符,实际传入的应当是一个char。void write(char[] data)void write(char[] data,int offset,int len)void write(String str) 直接写出一个字符串*/FileOutputStream fos = new FileOutputStream("osw.txt");OutputStreamWriter osw = new OutputStreamWriter(fos,StandardCharsets.UTF_8);String line = "如果你突然打了个喷嚏,那一定就是我在想你。";osw.write(line);//转换流的write(String str)会将写出的字符串转换为字节然后写出osw.write("如果半夜被手机吵醒,那一定就是我关心。");System.out.println("写出完毕!");osw.close();}
}
使用转换输入流读取文本文件
package io;import java.io.*;/*** 转换字符输入流* 可以将读取的字节按照指定的字符集转换为字符*/
public class ISRDemo {public static void main(String[] args) throws IOException {//将osw.txt文件中的所有文字读取回来.FileInputStream fis = new FileInputStream("osw.txt");InputStreamReader isr = new InputStreamReader(fis,"UTF-8");/*字符流读一个字符的read方法定义:int read()读取一个字符,返回的int值实际上表示的是一个char(低16位有效).如果返回的int值表示的是-1则说明EOF*///测试读取文件中第一个字
//        int d = isr.read();
//        char c = (char)d;
//        System.out.println(c);//循环将文件所有字符读取回来int d;while((d = isr.read()) != -1){System.out.print((char)d);}isr.close();}
}
转换流的意义:

实际开发中我们还有功能更好用的字符高级流.但是其他的字符高级流都有一个共通点:不能直接连接在字节流上.而实际操作设备的流都是低级流同时也都是字节流.因此不能直接在流连接中串联起来.转换流是一对可以连接在字节流上的字符流,其他的高级字符流可以连接在转换流上.在流连接中起到"转换器"的作用(负责字符与字节的实际转换)

总结

java将流分为两类:节点流与处理流:
  • 节点流:也称为低级流.

    节点流的另一端是明确的,是实际读写数据的流,读写一定是建立在节点流基础上进行的.

  • 处理流:也称为高级流.

    处理流不能独立存在,必须连接在其他流上,目的是当数据流经当前流时对数据进行加工处理来简化我们对数据的该操作.

实际应用中,我们可以通过串联一组高级流到某个低级流上以流水线式的加工处理对某设备的数据进行读写,这个过程也成为流的连接,这也是IO的精髓所在.

缓冲流

缓冲流是一对高级流,在流链接中链接它的目的是加快读写效率。缓冲流内部默认缓冲区为8kb,缓冲流总是块读写数据来提高读写效率

java.io.BufferedOutputStream缓冲字节输出流,继承自java.io.OutputStream

常用构造器
  • BufferedOutputStream(OutputStream out):创建一个默认8kb大小缓冲区的缓冲字节输出流,并连接到参数指定的字节输出流上。
  • BufferedOutputStream(OutputStream out,int size):创建一个size指定大小(单位是字节)缓冲区的缓冲字节输出流,并连接到参数指定的字节输出流上。
常用方法
flush():强制将缓冲区中已经缓存的数据一次性写出缓冲流的写出方法功能与OutputStream上一致,需要知道的时write方法调用后并非实际写出,而是先将数据存入缓冲区(内部的字节数组中),当缓冲区满了时会自动写出一次。

java.io.BufferedInputStream缓冲字节输出流,继承自java.io.InputStream

常用构造器
  • BufferedInputStream(InputStream in):创建一个默认8kb大小缓冲区的缓冲字节输入流,并连接到参数指定的字节输入流上。
  • BufferedInputStream(InputStream in,int size):创建一个size指定大小(单位是字节)缓冲区的缓冲字节输入流,并连接到参数指定的字节输入流上。
常用方法
缓冲流的读取方法功能与InputStream上一致,需要知道的时read方法调用后缓冲流会一次性读取缓冲区大小的字节数据并存入缓冲区,然后再根据我们调用read方法读取的字节数进行返回,直到缓冲区所有数据都已经通过read方法返回后会再次读取一组数据进缓冲区。即:块读取操作

对象流

对象流是一对高级流,在流链接中的作用是完成对象的序列化反序列化

序列化:是对象输出流的工作,将一个对象按照其结构转换为一组字节的过程。

反序列化:是对象输入流的工作,将一组字节还原为对象的过程。

java.io.ObjectInputStream对象输入流,继承自java.io.InputStream

常用构造器

ObjectInputStream(InputStream in):创建一个对象输入流并连接到参数in这个输入流上。

常用方法

Object readObject():进行对象反序列化,将读取的字节转换为一个对象并以Object形式返回(多态)。

如果读取的字节表示的不是一个java对象会抛出异常:java.io.ClassNotFoundException

java.io.ObjectOutputStream对象输出流,继承自java.io.OutputStream

常用构造器

ObjectOutputStream(OutputStream out):创建一个对象输出流并连接到参数out这个输出流上

常用方法

void writeObject(Object obj):进行对象的序列化,将一个java对象序列化成一组字节后再通过连接的输出流将这组字节写出。

如果序列化的对象没有实现可序列化接口:java.io.Serializable就会抛出异常:java.io.NotSerializableException

序列化接口java.io.Serrializable

该接口没有任何抽象方法,但是只有实现了该接口的类的实例才能进行序列化与反序列化。

实现了序列化接口的类建议显示的定义常量:static final long serialVersionUID = 1L;

可以为属性添加关键字transient,被该关键字修饰的属性在序列化是会被忽略,达到对象序列化瘦身的目的。

字符流

java将流按照读写单位划分为字节与字符流。字节流以字节为单位读写,字符流以字符为单位读写。

转换流java.io.InputStreamReader和OutputStreamWriter

功能无需掌握,了解其核心意义:

1:衔接其它字节与字符流

2:将字符与字节进行转换

相当于是现实中的"转换器"

化的对象没有实现可序列化接口:java.io.Serializable就会抛出异常:java.io.NotSerializableException**

序列化接口java.io.Serrializable

该接口没有任何抽象方法,但是只有实现了该接口的类的实例才能进行序列化与反序列化。

实现了序列化接口的类建议显示的定义常量:static final long serialVersionUID = 1L;

可以为属性添加关键字transient,被该关键字修饰的属性在序列化是会被忽略,达到对象序列化瘦身的目的。

字符流

java将流按照读写单位划分为字节与字符流。字节流以字节为单位读写,字符流以字符为单位读写。

转换流java.io.InputStreamReader和OutputStreamWriter

功能无需掌握,了解其核心意义:

1:衔接其它字节与字符流

2:将字符与字节进行转换

相当于是现实中的"转换器"

JavaApi:高级流相关推荐

  1. Linux 工具 | 第1篇:高级流控-TC+HTB+IFB+内核模块

    作者:isshe 日期:2018.09.19 邮箱:i.sshe@outlook.com github: https://github.com/isshe 高级流控-TC+HTB+IFB+内核模块 1 ...

  2. 【java基础,IO合集】文件流、高级流(缓冲流、对象流)、 序列化接口java.io.Serrializable

    目录 文件流 1 块读写的文件复制操作 2 文件输出流-覆盖模式 3 文件输出流-追加模式 4 文件输出流-读取文本数据 高级流 1  流连接示意图 2 缓冲流 2.1 使用缓冲流完成文件复制操作 2 ...

  3. JAVA基础-高级流

    day03 高级流 流连接示意图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2bvEvsS2-1651669628970)(image-20210528141614 ...

  4. java高级流低级流定义_java中哪些是低级流?哪些是高级流?

    引用来自"静心天涯"的评论 在输入输出里,有字节流和字符流分,这两者区别在于所操作的数据单元不同.还有另外一种认识,输入输出流可以分为节点刘和处理流(包装流),节点流有时候会被称为 ...

  5. java高级-----流

    **流的分类 1.按照流向分为:{输出流:OutputStream和Writer作为基类 输入流:InputStream和Reader作为基类} 2.按照数据处理的单元分为:{字节流:{字节流输入:I ...

  6. java之十 高级IO流

    视频课堂:https://edu.csdn.net/course/play/8222 java.io定义的输入/输出类列于下表: ObjectInputStream.GetField和ObjectOu ...

  7. day04--java高级编程:API:Object、String,Buffer、包装类、日期、java比较器、BigInteger、进制、length区别,IO流,路径,序列化id,编码

    1 API 1.1 Api文档下载 1.API (Application Programming Interface,应用程序编程接口)是 Java 提供的基本编程接口,一切可以调用的东西都是API. ...

  8. IO流(文件的读写)---本文的正确性有待您验证。

    2019独角兽企业重金招聘Python工程师标准>>> JAVA的I/O介绍.<<疯狂JAVA编程>>第15章有详细介绍,如下: http://www.cnb ...

  9. java--IO流(详)

    IO流也称为输入.输出流,就是用来读写数据的. 一.概述: 1.IO流的作用? 读写文件数据的 2.IO流是怎么划分的,大体分为几类,各自的作用? 字节流:字节输入流,字节输出流(读写字节数数据的) ...

最新文章

  1. 【扫盲帖】Java、JavaScript、JSP、JScript 的区别与联系
  2. 关于Response.redirect和Response.End出现线程中止异常的处理
  3. 腾讯云云机安装dockers
  4. 视觉检测无脊椎机器人或vipir_深入浅出人工智能前沿技术—机器视觉检测,看清人类智慧工业...
  5. 图解Http学习第三章
  6. 今天,我背完了考研5500词!!!
  7. Urllib库的基本使用
  8. python短期电力预测——基于LSTM神经网络
  9. Linux中vdbench的安装与使用
  10. 智慧城市数字孪生IOC系统
  11. 2019很艰难,2020会更好吗
  12. 录屏怎么录?你知道多少录屏软件?
  13. GSR2501国产2.4G PA替代RFX2401C,AT2401C,RT201
  14. buctoj 2407 B 竖式 题解
  15. godoc使用方法介绍
  16. LVS负载均衡群集—NAT模式实例
  17. 不填写内容用哪个斜杠代替_斜杠可以代替顿号在句子中使用吗
  18. Java — 内部类存在意义
  19. 《笨方法学 Python 3》43.基本的面向对象分析和设计
  20. fp函数式编程_全面了解函数式编程(FP)

热门文章

  1. orangepi升级linux内核,orangePi源码编译教程
  2. PS人物脸部去高光简单之法
  3. webService初识
  4. 原来这就是Java中的异常(abnormal),小白看完也懂了,学习总结①
  5. 微信小程序入门2-创建一个微信小程序
  6. 如何在微信推文中插入b站_视频引流:如何把B站的流量引流到微信?
  7. 基于itext5动态生成pdf带分页,自定义字体
  8. unity 曲线可视化图表制作(lineRenderer + 贝塞尔曲线)
  9. 计算机统考本科,[2017年电大]电大本科计算机统考[呕心沥血整理].doc
  10. Verilog学习笔记