JavaEE 初阶篇-深入了解 I/O 高级流(缓冲流、交换流、数据流和序列化流)

🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍

文章目录

        1.0 缓冲流概述

        1.1 缓冲流的工作原理

        1.2 使用缓冲流的步骤

        1.3 字节缓冲流于字符缓冲流的区别

        1.4 字节缓冲流的实例

        1.5 字符缓冲流的实例

        2.0 转换流概述

        2.1 字符输入转换流的实例( InputStreamReader 类)

        2.2 字符输出转化流的实例(OutputStreamWriter 类)

        3.0 打印流概述

        3.1 字节打印流(PrintStream 类)

        3.2 字符打印流(PrintWrite 类)

        4.0 数据流概述

        4.1 数据输出流(DataOutputStream 类)

        4.2 数据输入流(DataInputStream 类)

        5.0 序列化流概述

        5.1 对象字节输出流(ObjectOutputStream 类)

        5.2 对象字节输入流(ObjectInputStream 类)


        1.0 缓冲流概述

        缓冲流(Buffered Stream)来提高 I/O 操作的效率,缓冲流是对字节流和字符流的一种封装,通过缓冲区来减少 I/O 操作的次数,从而提高程序的运行效率。缓冲流的实现类有 BufferedInputStream、BufferedOutputStream、BufferedReader 和 BufferedWriter 。

        1.1 缓冲流的工作原理

        在读取数据时,缓冲流会将数据先读入缓冲区,等到缓冲区满或者达到一定条件时,再将缓冲区中的数据一次性写入到目标设备中;在写入数据时,缓冲流会将数据先写入缓冲区,等到缓冲区满或者达到一定条件时,再将缓冲区中的数据一次性写入到目标设备中。

        1.2 使用缓冲流的步骤

        1)创建字节流或者字符流对象。

        2)将字节流或字符流对象作为参数创建缓冲流对象。

        3)通过缓冲流对象进行数据读取获取写入操作

        4)关闭缓冲流对象,同时会自动关闭底层的字节流或字符流对象。

        1.3 字节缓冲流于字符缓冲流的区别

        1)字节缓冲流会在内存中分配一个大小为 8 KB 的缓冲区来存储数据。这个缓冲区会在读取或写入数据时起到缓冲作用,减少对底层输入流或输出流的直接访问,提高读写效率。

        2)字符缓冲流会在内存中分配 8K(8192)的字符缓冲池,可以提高字符输入流读取字符数据的性能。

        3)字符缓冲流特有方法:

        public String readLine() throws IOException:读取一行字符数据,以换行符为结束标志,返回读取的字符串(不包括换行符)。

        public void newLine() throws IOException:写入一个换行符,根据系统的换行符规范来写入换行符。

        1.4 字节缓冲流的实例

        1)字节输出缓冲流来进行写文件操作

代码如下:

import java.io.*;public class BufferedOut {public static void main(String[] args) throws IOException {OutputStream os = new FileOutputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_25\\src\\MyIO\\Text.text");//将低级流转化为高级流BufferedOutputStream bos = new BufferedOutputStream(os);bos.write('a');bos.write('b');bos.write('c');bos.write('d');bos.write('f');bos.write('g');//关闭高级流,系统就会自动关闭低级流bos.close();}
}

运行结果:

        2)字节输入缓冲流来进行读文件操作

代码如下:

import java.io.*;public class BufferedIs {public static void main(String[] args) throws IOException {InputStream is = new FileInputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_25\\src\\MyIO\\Text.text");//将低级流转化为高级流BufferedInputStream bis = new BufferedInputStream(is);int len;while ((len = bis.read()) != -1){System.out.print((char) len);}}
}

运行结果:

        1.5 字符缓冲流的实例

        1)字符输出缓冲流来进行写文件操作。

代码如下:

import java.io.*;public class BufferedW {public static void main(String[] args) throws IOException {//先创建字符流(低级流)Writer writer = new FileWriter("D:\\software\\code\\2023_java\\2023_java_code\\code_24_25\\src\\MyIO\\Text.text");//将低级流转化为高级流BufferedWriter bw = new BufferedWriter(writer);//开始写文件操作bw.write("字符缓冲流内部的缓冲区大小通常是比较合适的,一般在 8 KB 到 16 KB 之间。");//刷新数据bw.flush();//换行操作bw.newLine();bw.write("这个大小是经过实际测试和性能优化的,能够在提高读写效率的同时,又不会占用过多的内存。");//操作完毕之后,需要关闭资源,关闭高级流,低级流也会自动关闭的。bw.close();}
}

运行结果:

        2)字符输入缓冲流进行将文件的内容进行打印

代码如下:

import java.io.*;public class BufferedR {public static void main(String[] args) throws IOException {Reader reader = new FileReader("D:\\software\\code\\2023_java\\2023_java_code\\code_24_25\\src\\MyIO\\Text.text");BufferedReader br = new BufferedReader(reader);//开始读文件操作String len;while ((len = br.readLine()) != null){System.out.println(len);}//结束程序需要关闭资源br.close();}
}

运行结果:

        2.0 转换流概述

        在 Java 中,字符流和字节流之间存在着转换的需求。字符流用于处理文本数据,而字节流用于处理二进制数据。转换流提供了 InputStreamReader 和 OutputStreamWriter 两个类,用于将字节流转换为字符流或将字符流转换为字节流。

        InputStreamReader 类从字节流中读取数据,并根据指定的字符编码将字节数据转换为字符数据;OutputStreamWriter 类将字符数据按照指定的字符编码转换为字节数据并写入到字节流中。

转换流的主要作用包括:

        1)字节流和字符流之间的转换:转换流可以方便地将字节流转换为字符流,或将字符流转换为字节流。

        2)字符编码和解码:转换流可以指定字符编码,用于将字节数据转换为字符数据或将字符数据转换为字节数据。

        3)处理文本数据:转换流通常用于处理文本数据,提供了更方便的字符操作方法。

        2.1 字符输入转换流的实例( InputStreamReader 类)

        简单来说,InputStreamReader 将读取的字节流转化为字符流,并且如果读取的是用 GBK 编码集进行编码的,在 UTF 环境下进行编码时,则需要指定用 GBK 编码集进行编码。

代码如下:

import java.io.*;public class demo1 {public static void main(String[] args) throws FileNotFoundException {try(InputStream inputStream = new FileInputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\ExchangeStreams\\Text");//将读取的文件字节流转化为字符流,并指定用GBK编码集进行编码Reader inputStreamReader = new InputStreamReader(inputStream,"GBK");//再将其转化为缓冲流BufferedReader br = new BufferedReader(inputStreamReader);){String str;while ((str = br.readLine()) != null){System.out.println(str);}} catch (Exception e) {e.printStackTrace();}}
}

运行结果:

        2.2 字符输出转化流的实例(OutputStreamWriter 类)

        简单来说,把原始的字节输出流,按照指定的字符集编码转换成字符输出转换流。就是将字节输出流转换为字符输出流,并且按指定的编码集编码输出。

代码如下:

import java.io.*;public class demo2 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\ExchangeStreams\\T");//将字节输出流转化为字符输出转换流Writer osw = new OutputStreamWriter(outputStream,"GBK");//再将字符输出转化流升级为缓冲流BufferedWriter bw = new BufferedWriter(osw);) {bw.write("在这个美丽的世界里,每一天都是新的开始。阳光洒在大地上,微风拂过脸庞,让人感受到生命的美好。");bw.newLine();bw.write("无论遇到怎样的困难和挑战,我们都要勇敢面对,坚定前行。生活充满了无限可能,让我们抓住每一个机会,追逐自己的梦想。");bw.newLine();bw.write("愿每个人都能拥有快乐与幸福,享受生活的点滴美好。");}catch (IOException e){e.printStackTrace();}}
}

        3.0 打印流概述

        打印流 :PrintStream 和 PrintWriter 是 Java I/O 中的高级流,用于将各种数据类型格式化并输出到目标设备,如控制台、文件或网络连接。PrintStream 和 PrintWriter 提供了方便的方法来输出各种数据类型,包括基本数据类型、字符串、对象等。

        简单来说:打印什么内容,就会输出什么内容。

        3.1 字节打印流(PrintStream 类)

构造方法:

        1)public PrintStream(OutputStream/File/String):打印流直接通向字节输出流/文件/文件路径。

        2)public PrintStream(String fileName,Charset charset):可以指定写出去的字符编码。

        3)public PrintStream(OutputStream out,boolean autoFlush):可以指定实现自动刷新。

        4)public PrintStream(OutputStream out,boolean autoFlush,String encoding):可以指定实现自动刷新,并可指定字符的编码。

常用的方法:

        1)public void println(xxx):打印任意类型的数据出去。

        2)public void write(int / byte[] / byte[] 一部分):可以支持写字节数据出去。

代码演示:

import java.io.IOException;
import java.io.PrintStream;public class MyPrintStream {public static void main(String[] args) {try(PrintStream printStream = new PrintStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Print\\TT")){//打印啥就会输出啥printStream.println(111);printStream.println( );printStream.println('A');printStream.println("你好世界");printStream.println("你好小鸭");printStream.println();printStream.println("你好小扳");//支持输出字节数据printStream.write(98);printStream.write('A');printStream.write("你好小狗".getBytes());}catch (IOException e){e.printStackTrace();}}
}

运行结果:

        3.2 字符打印流(PrintWrite 类)

构造方法:

        1)public PrintWrite(OutputStream/File/String/Write):打印流直接通向字节输出流/文件/文件路径/字符输出流。

        2)public PrintWrite(String fileName,Charset charset):可以指定写出去的字符编码。

        3)public PrintWrite(OutputStream out/Write,boolean autoFlush):可以指定实现自动刷新。

        4)public PrintWrite(OutputStream out,boolean autoFlush,String encoding):可以指定实现自动刷新,并可指定字符的编码。

常用的方法:

        1)public void println(xxx):打印任意类型的数据出去,打印什么就输出什么内容。

        2)public void write(int/String/char[]/...):可以支持写字符数据出去。

代码演示:

import java.io.IOException;
import java.io.PrintWriter;public class MyPrintWrite {public static void main(String[] args) {try(PrintWriter printWriter = new PrintWriter("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Print\\TT")){printWriter.println(1);printWriter.println("你好鸭小鸭");printWriter.println("你好鸭小猫");printWriter.println("你好鸭小狗");printWriter.println();printWriter.println("A");printWriter.println('a');printWriter.println("你好鸭小板");//还支持字符输入流printWriter.write(98);printWriter.write("A");printWriter.write("你好鸭小童");}catch (IOException e){e.printStackTrace();}}
}

运行结果:

补充:如果需要追加数据,则需要用到低级流对象作为高级流的参数,低级流构造器中第二个参数 true 可以实现数据追加。

代码如下:

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;public class MyPrintWrite {public static void main(String[] args) {try(PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Print\\TT",true))){printWriter.println(1);printWriter.println("你好鸭小鸭");printWriter.println("你好鸭小猫");printWriter.println("你好鸭小狗");printWriter.println();printWriter.println("A");printWriter.println('a');printWriter.println("你好鸭小板");//还支持字符输入流printWriter.write(98);printWriter.write("A");printWriter.write("你好鸭小童");}catch (IOException e){e.printStackTrace();}}
}

运行结果:

        4.0 数据流概述

        数据流是 Java I/O 中的一种特殊流,用于读取或写入原始数据类型(如 int、double、char 等)而不是字节或字符。数据流提供了方便的方法来读取和写入基本数据类型,避免了手动进行数据类型转换的繁琐工作。

        在 Java 中,数据流主要包括 DataInputStream 和 DataOutputStream。它们分别是字节数据流和字符数据流的装饰器,可以包装其他输入流或输出流,以便读取或写入基本数据类型。

        适用于网络通信和文件操作:数据流常用于网络通信和文件操作中,方便地读取和写入基本数据类型。

        4.1 数据输出流(DataOutputStream 类)

构造方法:

        public DataOutputStream(OutputStream out):创建新数据输出包装基础的字节输出流。

常用的方法:

        1)public final void writeByte(byte v):将 byte 类型的数据写入基础的字节输出流。

        2)public final void writeInt(int v):将 int 类型的数据写入基础的字节输出流。

        3)public final void writeDouble(Double v):将 double 类型的数据写入基础的字节输出流。

        4)public final void writeUTF(String str):将字符串数据以 UTF-8 编码成字节写入基础的字节输出流。

        5)public void write(int/byte[]/byte[] 一部分):支持写字节数据出去。

代码演示:

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class MyDataInOutStream {public static void main(String[] args) {//先创建低级输出流try(OutputStream os = new FileOutputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Data\\DataText");//再继续转化为高级流DataOutputStream dos = new DataOutputStream(os);){dos.writeByte(1);dos.writeInt(333);dos.writeDouble(333.01);dos.writeUTF("你好鸭小蜜蜂!!!!");}catch (IOException e){e.printStackTrace();}}
}

运行结果:

        需要注意的是:这是正常的情况而不是乱码,这是一个特殊的存储方法,可以理解为将类型和内容进行了“打包”。主要是为了,方便取数据而不是给程序员看的。

        4.2 数据输入流(DataInputStream 类)

        用于读取数据输出流写出去的数据。注意读取的顺序应该跟写数据的顺序保持一致。

构造方法:

        public DataInputStream(InputStream is):创建新数据输入流包装基础的字节输入流。

常用的方法:

        1)public final byte readByte():读取字节数据返回。

        2)public final int readInt():读取 int 类型的数据返回。

        3)public final double readDouble():读取 double 类型的数据返回。

        4)public final String readUTF():读取字符串(UTF-8)数据返回。

        5)public int read(byte[]):支持字节数据进来。

代码演示:

import java.io.*;public class MyDataInputStream {public static void main(String[] args) {try(InputStream inputStream = new FileInputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Data\\DataText");DataInputStream dis = new DataInputStream(inputStream);){byte b = dis.readByte();System.out.println(b);int i = dis.readInt();System.out.println(i);double dl = dis.readDouble();System.out.println(dl);String str = dis.readUTF();System.out.println(str);}catch (IOException e){e.printStackTrace();}}
}

运行结果:

        5.0 序列化流概述

        序列化流是 Java I/O 中的一种特殊流,用于将对象转换为字节序列以便存储或传输,或将字节序列转换回对象。序列化流主要用于实现对象的持久化存储和网络传输。

        在 Java 中,常用的序列化流包括 ObjectOutputStream 和 ObjectInputStream。它们可以分别用于将对象写入输出流并序列化为字节流,以及从输入流中读取字节流并反序列化为对象。

特点:

        将对象转换为字节序列:序列化流可以将 Java 对象转换为字节序列,以便存储在文件中或通过网络传输。

        反序列化:序列化流也可以将字节序列反序列化为对象,恢复对象的状态。

        注意:对象如果需要序列化,必须实现序列化接口( Serializable )。

        5.1 对象字节输出流(ObjectOutputStream 类)

        可以把 Java 对象进行序列化,把 Java 对象存入到文件中去。

构造方法:

        public ObjectOutputStream(OutputStream out):创建对象字节输出流,包装基础的字节输出流。

常用方法:

        public final void writeObject(Object o):把对象写出去。

代码演示:

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;public class MyObjectOutputStream {public static void main(String[] args) {try(//先创建一个低级输出流OutputStream os = new FileOutputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Object\\ObjectText");//创建序列化流ObjectOutputStream oos = new ObjectOutputStream(os);){//将用户对象写入到文件中User user = new User("小蜜蜂","001",18,"123456");oos.writeObject(user);System.out.println("序列化创建成功!!!");}catch(Exception e){e.printStackTrace();}}
}

运行结果:

        注意:以上的情况不是出现乱码,是属于正常情况。将对象写进文件中,不是给人看的,为了方便取数据。

        5.2 对象字节输入流(ObjectInputStream 类)

        把 Java 对象进行反序列化:把存储再文件中的 Java 对象读入到内存中来。

构造方法:

        public ObjectInputStream(InputStream is):创建对象字节输入流,包装基础的字节输入流。

常用的方法:

        public final Object readObject():把存储在文件中的 Java 对象读出来。

代码演示:

import java.io.FileInputStream;
import java.io.ObjectInputStream;public class MyObjectInputStream {public static void main(String[] args) {try(//低级输出流//再利用低级流作为参数来创建对象输出流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Object\\ObjectText"));){User user = (User) ois.readObject();//将对象进行输出System.out.println(user);}catch (Exception e){e.printStackTrace();}}
}

运行结果:

        假设:需求进行序列化的时候,不能将密码进行序列化操作,则可以用 transient 修饰成员变量。

        这样就序列化的时候,不会将密码这个成员变量进行序列化操作。

代码演示:

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;public class MyObjectOutputStream {public static void main(String[] args) {try(//先创建一个低级输出流OutputStream os = new FileOutputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Object\\ObjectText");//创建序列化流ObjectOutputStream oos = new ObjectOutputStream(os);){//将用户对象写入到文件中User user = new User("小蜜蜂","001",18,"123456");oos.writeObject(user);System.out.println("序列化创建成功!!!");}catch(Exception e){e.printStackTrace();}}
}
import java.io.FileInputStream;
import java.io.ObjectInputStream;public class MyObjectInputStream {public static void main(String[] args) {try(//低级输出流//再利用低级流作为参数来创建对象输出流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_4_26\\src\\Object\\ObjectText"));){User user = (User) ois.readObject();//将对象进行输出System.out.println(user);}catch (Exception e){e.printStackTrace();}}
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/651040.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

去年十八,初识Java 2

我的Python和PHP是怎么学的?是直接写项目,在项目中学的。 不过…这招到 java 里好像不好使了QAQ 零、前置基础 1、类的继承 在 Java 中,extends 用于创建类的继承关系。当一个类继承另一个类时,它会获得父类的属性和方法&…

AS-V1000 视频监控平台,如何实现设备上线、下线时产生告警,及时通知管理人员

目录 一、客户需求 (一)客户需求 (二)掌握设备状况的意义 1、实时故障检测与预警 2、提升系统可靠性 3、优化资源配置 4、增强安全保障 5、提升管理效率 二、产品介绍 三、系统配置 (一)实现告警…

python基础——正则表达式

📝前言: 这篇文章主要想讲解一下python中的正则表达式: 1,什么是正则表达式 2,re模块三匹配 3,元字符匹配 4,具体示例 🎬个人简介:努力学习ing 📋个人专栏&am…

什么是用户体验(UX)文案,为什么它很重要?

网上购物如今比以往任何时候都更加相关。所以我们将以此为例说明什么是用户体验(UX)文案,以及为什么它很重要。 假设你去了一个在线商店。你需要执行一系列操作: 找到合适的部分选择你感兴趣的产品弄清楚它们是什么,…

屌爆了,国产智能体的爆发性增长:一周数据揭秘

前言 自从4.19接入国内智能体 探索国产智能体:从GPTs使用热潮到本土模型的崛起 截止到今天(4.26),仅仅一周时间,数据太让我意外了,这篇文章就来总结一下! 这一次,我为国产智能体崛起,代言!!! 惊…

软件设计师-重点的创建型设计模式

一、简单工厂: 简单工厂模式属于创建型模式,但不属于23种设计模式之一。 软考中图 二、工厂方法: 意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。 结…

自动驾驶传感器篇: GNSSIMU组合导航

自动驾驶传感器篇: GNSS&IMU组合导航 1.GNSS1.1 GNSS 系统概述1.2 GNSS系统基本组成1. 空间部分(Space Segment):2. 地面控制部分(Ground Control Segment):3. 用户设备部分(Use…

ElasticSearch 安装(docker)

下载安装包 阿里云链接: elasticSearch.exe https://www.alipan.com/s/3A356NnmWaJ 提取码: 93da 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。 安装步骤 1、首先…

使用 Docker 部署 TailChat 开源即时通讯平台

1)介绍 TailChat 官网: https://tailchat.msgbyte.com/ 作者:https://www.moonrailgun.com/about/ GitHub : https://github.com/msgbyte/tailchat TailChat 是一款插件化易拓展的开源 IM 应用。可拓展架构赋予 Tailchat 无限可能…

【C语言必刷题】7. 百钱百鸡

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…

【Linux】如何进行用户之间的切换——指令su

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

019基于JavaWeb的在线音乐系统(含论文)

019基于JavaWeb的在线音乐系统(含论文) 开发环境: Jdk7(8)Tomcat7(8)MysqlIntelliJ IDEA(Eclipse) 数据库: MySQL 技术: JavaServletJqueryJavaScriptAjaxJSPBootstrap 适用于: 课程设计,毕…