字符输出流,缓冲流和序列化

1. IO流

1.1 文件操作字符输出流
FileWriter文件操作输出字符流Constructor 构造方法FileWriter(File file);根据File类对象创建对应文件的文件操作输出字符流FileWriter(String pathName);根据String类型文件路径创建对应文件的文件操作输出字符流FileWriter(File file, boolean append);根据File类对象创建对应文件的文件操作输出字符流,并要求为追加写FileWriter(String pathName, boolean append);根据String类型文件路径创建对应文件的文件操作输出字符流,并要求为追加写如果创建FileWrite对象时,这里文件不存在,路径合法,这里会创建对应的操作文件。如果路径不合法,抛出异常 FileNotFoundException Method 成员方法 void write(int ch);写入一个char类型数据到文件中void write(char[] arr);写入一个char类型数组到文件中void write(char[] arr, int offset, int length);   写入一个char类型数组到文件中,要求从offset下标位置开始读取数组数据,长度为lengthvoid write(String str);写入一个字符串到文件中void write(String str, int offset, int lenght);写入一个字符串到文件中,要求从指定字符串offset下标位置开始,长度为length如果写入数据操作过程中,发生问题,这里会有一个IOException
1.2 使用演示
package com.qfedu.b_io;import java.io.File;
import java.io.FileWriter;
import java.io.IOException;/** 文件操作字符输出流*/
public class Demo1 {public static void main(String[] args) {FileWriter fileWriter = null;try {fileWriter = new FileWriter(new File("D:/aaa/5.txt"), true);char[] charArray = "现在美国全国缺少口罩2.7亿".toCharArray();fileWriter.write(charArray);fileWriter.write("韩国目前疫情情况不容乐观");fileWriter.write("\r\n");fileWriter.write(charArray, 0, 5);fileWriter.write("韩国目前疫情情况不容乐观", 0, 5);} catch (IOException e) {e.printStackTrace();} finally {if (fileWriter != null) {try {fileWriter.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}private static void writeTest1() {FileWriter fileWriter = null;try {fileWriter = new FileWriter(new File("D:/aaa/4.txt"), true);fileWriter.write('武');fileWriter.write('汉');fileWriter.write('加');fileWriter.write('油');fileWriter.write(',');fileWriter.write('中');fileWriter.write('国');fileWriter.write('加');fileWriter.write('油');fileWriter.write(',');fileWriter.write('世');fileWriter.write('界');fileWriter.write('加');fileWriter.write('油');} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (fileWriter != null) {try {fileWriter.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}
1.3 字符流文件拷贝
package com.qfedu.b_io;import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;/** 使用文件操作字符流量拷贝非文本文件问题* 【要求】*       禁止使用字符流操作非文本文件,记事本打开乱码文件都不可以*/
public class Demo2 {public static void main(String[] args) {FileReader fileReader = null;FileWriter fileWriter = null;try {fileReader = new FileReader(new File("D:/aaa/logo桌面.jpg"));fileWriter = new FileWriter(new File("D:/aaa/temp.jpg"));char[] buf = new char[1024 * 4];int length = -1;while ((length = fileReader.read(buf)) != -1) {fileWriter.write(buf, 0, length);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (fileWriter != null) {try {fileWriter.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (fileReader != null) {try {fileReader.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}

2. 缓冲流

2.1 缓冲流有什么作用
使用缓冲数组以后,整体的读取,写入效率提升很大!!!
降低了CPU通过内存访问硬盘的次数。提高效率,降低磁盘损耗。字节输入缓冲BufferedInputStream
字节输出缓冲BufferedOutputStream
字符输入缓冲BufferedReader
字符输出缓冲BufferedWrite【重点】所有的缓冲流都没有任何的读取,写入文件能力,这里都需要对应的输入流和输出流来提供对应的能力。在创建缓冲流流对象时,需要传入对应的输入流对象和输出流对象。底层就是提供了一个默认大小的缓冲数组,用于提高效率
2.2 字节缓冲流
输入BufferedInputStream(InputStream in);   这里需要的对象是一个字节输入流基类对象。同时也可也传入InputStream子类对象
输出BufferedOutputStream(OutputStream out);这里需要的对象是一个字节输出流基类对象。同时也可也传入OutputStream子类对象以上传入的InputStream和OutputStream都是用于提供对应文件的读写能力。
2.2.1 字节输入流缓冲效率问题
1. 在BufferedInputStream底层中有一个默认容量为8KB的byte类型缓冲数组。
2. fill方法是一个操作核心a. 从硬盘中读取数据,读取的数据容量和缓冲数组容量一致。b. 所有的read方法,都是从缓冲数组中读取数据c. 每一次读取数据之前,都会检查缓冲区内是否有数据,如果没有,fill方法执行,填充数据。3. 利用缓冲,fill方法,可以极大的降低CPU通过内存访问硬盘的次数。同时程序操作的数据是在内存中进行交互的。
2.2.2 字节输出流缓冲效率问题
1. 在BufferedOutputStream类对象,默认有一个8KB的byte类型缓冲数组
2. 数据写入文件时并不是直接保存到文件中,而是保存在内存8KB字节缓冲数组中
3. 如果8KB空间填满,会直接flush缓冲区,数据保存到硬盘中,同时清空整个缓冲区。
4. 在BufferedOutputStream关闭时,首先会调用flush方法,保存数据到文件,清空缓冲区,并且规划缓冲区占用内存,同时关闭缓冲流使用的字节输出流。
2.2.3 缓冲流拷贝和非缓冲拷贝时间效率区别
package com.qfedu.c_buffered;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class Demo3 {public static void main(String[] args) {long start = System.currentTimeMillis();copy();long end = System.currentTimeMillis();// 总耗时System.out.println("Time:" + (end - start));}// 1716 mspublic static void useBuffered() {BufferedInputStream bis = null;BufferedOutputStream bos = null;try {bis = new BufferedInputStream(new FileInputStream(new File("D:/aaa/2.txt")));bos = new BufferedOutputStream(new FileOutputStream(new File("D:/aaa/buffered.txt")));int content = -1;while ((content = bis.read()) != -1) {bos.write(content);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (bos != null) {try {bos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (bis != null) {try {bis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}// 531000public static void copy() {FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream("D:/aaa/2.txt");fos = new FileOutputStream("D:/aaa/copy.txt");int content = -1;while ((content = fis.read()) != -1) {fos.write(content);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (fos != null) {try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (fis != null) {try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}
2.3 字符缓冲流
BufferedReader字符缓冲输入流BufferedReader(Reader reader);
BufferedWriter字符缓冲输出流BufferedWriter(Writer writer);
2.3.1 字符缓冲流效率问题
1. 字符缓冲输入流,底层有一个8192个元素的缓冲字符数组,而且使用fill方法从硬盘中读取数据填充缓冲数组2. 字符缓冲输出流,底层有一个8192个元素的缓冲字符数组,使用flush方法将缓冲数组中的内容写入到硬盘当中。3. 使用缓冲数组之后,程序在运行的大部分时间内都是内存和内存直接的数据交互过程。内存直接的操作效率是比较高的。并且降低了CPU通过内存操作硬盘的次数4. 关闭字符缓冲流,都会首先释放对应的缓冲数组空间,并且关闭创建对应的字符输入流和字符输出流。5.
字符缓冲输入流中String readLine(); 读取一行数据
字符缓冲输出流中void newLine(); 换行

3. 项目中使用IO流和文件保存数据

Student类内需要保存的核心数据学生的信息count 学生ID计数器文件操作这两个方法,我们做出一个工具类保存在程序退出之前保存学生数据存储于StudentManager对象中StudentManager中存储数据使用的结构是ArrayList从ArrayList中读取每一个学生数据,保存到文件中,最后保存count文件:[6,骚磊,16,男,99,95,97,291,0][7,骚磊,16,男,99,95,97,291,0][8,骚磊,16,男,99,95,97,291,0][9,骚磊,16,男,99,95,97,291,0]count:20读取在程序启动之前读取数据判断 [读取一行内容,解析一行内容,创建一个Student对象,保存到StudentManager中[6,骚磊,16,男,99,95,97,291,0] subString ==> 6,骚磊,16,男,99,95,97,291,0split(",") ==> String[] array = {"6","骚磊","16","男","99","95","97","291","0"}解析String ==> 目标数据类型 int char 判断 csplit(":") ==> String[] arr = {"count" , "20"};解析20
package com.system.student.qfedu.util;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;import com.system.student.qfedu.entity.Student;
import com.system.student.qfedu.manager.StudentManager;public class DataUtils {/*** 从文件中读取数据到StudentManager对象中* * @param studentManager 学生管理类对象*/public static void readData(StudentManager studentManager) {/*[11,千锋学生6,156,男,39,95,97,231,0][12,千锋学生7,166,男,119,95,97,311,0][13,千锋学生8,126,男,90,95,97,282,0][14,千锋学生9,360,男,60,95,97,252,0]count:15*/BufferedReader br = null;try {br = new BufferedReader(new FileReader(new File("./data/students.txt")));String data = null;while ((data = br.readLine()) != null) {if ('[' == data.charAt(0)) {// 学生数据String[] split = data.substring(1, data.length() - 1).split(",");// 解析数组中每一个元素对应数据int id = Integer.parseInt(split[0]);String name = split[1];int age = Integer.parseInt(split[2]);char gender = split[3].charAt(0);int mathScore = Integer.parseInt(split[4]);int chnScore = Integer.parseInt(split[5]);int engScore = Integer.parseInt(split[6]);int totalScore = Integer.parseInt(split[7]);int rank = Integer.parseInt(split[8]);// 创建Student类对象,存储到StudentManager中Student stu = new Student(id, name, age, gender, mathScore, chnScore, engScore, totalScore, rank);studentManager.add(stu);} else if ('c' == data.charAt(0)) {// count数据 count:20Student.setCount(Integer.parseInt(data.split(":")[1]));}}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 从StudentManager中保存数据到文件* * @param studentManager 学生管理类对象*/public static void saveData(StudentManager studentManager) {BufferedWriter bw = null;try {// 选择写入文件的方式是删除写!!!bw = new BufferedWriter(new FileWriter(new File("./data/students.txt")));// 获取StudentManager对象中保存的所有学生类对象数据Student[] allStudents = studentManager.getAllStudents();for (int i = 0; i < allStudents.length; i++) {// 写入学生数据bw.write(allStudents[i].getData());bw.newLine();}bw.write("count:" + Student.getCount());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (bw != null) {try {bw.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}

4. 序列化

4.1 序列化概述
Java中提供了一种序列化操作的方式,用一个字节序列化来表示一个对象,该字节序列化中保存了【对象的属性】,【对象的类型】和【对象的数据】。把字节序列化保存到文件中,就可以做到持久化保存数据内容。从文件中读取字节序列化数据,可以直接得到对应的对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avSyc4sl-1583162901517)(img/序列化和反序列化.png)]

4.2 ObjectOutputStream类
将对象数据序列化,保存到文件中构造方法 ConstructorObjectOutputStream(OutputStream out);输出字节流对象作为当前方法的参数
package com.qfedu.d_objectxxx;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class Demo1 {public static void main(String[] args) {ObjectOutputStream objectOutputStream = null;try {objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/aaa/person.txt"));// 序列化对象,并且写入到文件中objectOutputStream.writeObject(new Person(1, "骚磊", 16));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (objectOutputStream != null) {try {objectOutputStream.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}
4.3 ObjectInputStream类
从文件中读取被序列化之后的字节数据,提供反序列化操作,得到一个对象。构造方法 ConstructorObjectInputStream(InputStream in);需要提供一个字节输入流对象来进行操作
【序列化注意事项】
1. 如果一个类需要进行序列化操作,必须遵从。java.io.Serializable。不遵从无法进行序列化操作2. 序列化之后从文件中读取序列化内容,转换成对应的对象,ClassNotFoundException 对应类没有找到。对应的类型没有导包,不存在...InvalidClassException 类型不一样序列化之后的每一个类都会有一个serialVersionUID,该编号在使用过程中,序列化和反序列化必须一致3. transient 修饰的成员变量不能被序列化

ption e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}


##### 4.3 ObjectInputStream类

从文件中读取被序列化之后的字节数据,提供反序列化操作,得到一个对象。

构造方法 Constructor
ObjectInputStream(InputStream in);
需要提供一个字节输入流对象来进行操作


##### 【序列化注意事项】
  1. 如果一个类需要进行序列化操作,必须遵从。java.io.Serializable。不遵从无法进行序列化操作

  2. 序列化之后从文件中读取序列化内容,转换成对应的对象,
    ClassNotFoundException 对应类没有找到。
    对应的类型没有导包,不存在…
    InvalidClassException 类型不一样
    序列化之后的每一个类都会有一个serialVersionUID,该编号在使用过程中,序列化
    和反序列化必须一致

  3. transient 修饰的成员变量不能被序列化

字符输出流,缓冲流和序列化相关推荐

  1. 字符流、字节流、缓冲流、序列化流

    1.文件拷贝的基本代码 2.一次读取多个字节 3.异常处理 但是上述的释放过程太繁琐,于是便用AutoCloseable接口简化释放过程 JDK7: JDK9: 4.各种字词计算机存储规则 所以底层二 ...

  2. Java 之 Java 缓冲流与序列化

    缓冲流 缓冲流(高效率的流) BufferedOutputStream 缓冲输出字节流 构造方法: BufferedOutputStream(OutputStream out) 参数:字节输出流的父类 ...

  3. Java 字节区/字符区缓冲流

    零.复习昨日 File:通过路径代表一个文件或目录 方法:创建新,查找类 一.作业 给定路径删除文件夹 public static void main(String[] args){deletDir( ...

  4. 【Java I/O流】File、字符集、字节流、字符流、缓冲流、数据流、对象流、序列化、try-with-resources语句

    I/O流 File File 常用方法 File 练习:搜索.删除.剪切 字符集(Character Set) 字符编码(Character Encoding) 字符编码比较 乱码 try-with- ...

  5. 【Java-IO】File、搜索删除剪切、字符集、字符编码、字节流、将内存中的数据写入文件、字符流、缓冲流、Scanner、格式化输出、数据流、对象流、序列化与反序列化、Files工具类

    IO 文章目录 IO 简介 File 分隔符.大小写 常用方法 练习:搜索.删除.剪切 字符集(Character Set) 字符编码(Character Encoding) 字符编码比较 乱码 字节 ...

  6. 缓冲流,转换流,序列化流,网络编程

    一,缓冲流 能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等.这些功能更为强大的流,都是在基本的流对象基础之上创建而来的,相当于是对基本流对象的一种增强.1.1 概述 缓冲 ...

  7. java(十)【属性集,缓冲流、转换流、序列化流】

    day10[缓冲流.转换流.序列化流] 今日目标 IO资源的处理. finnally释放资源 jdk 1.7开始的新技术 try-with-resources 缓冲流 提高字节流和字符流读写数据的性能 ...

  8. 【缓冲流、转换流、序列化流】

    [缓冲流.转换流.序列化流] 今日目标 IO资源的处理. finnally释放资源 jdk 1.7开始的新技术 try-with-resources 缓冲流 提高字节流和字符流读写数据的性能的. 转换 ...

  9. day22【Properties、ResourceBundle工具类、缓冲流、转换流、序列化】课上

    1.属性集(掌握,很重要) 概念介绍 1.Properties,属于双列集合,他的父类Hashtable,jdk1.0就存在了. 2.该集合没有泛型,因为该集合中的存放数据类型都是String类型 3 ...

最新文章

  1. SwipeRefreshLayout和RecyclerView滑动冲突的解决
  2. 新茶饮“降价内卷”的尽头,是供应链?
  3. Matlab命令集--常用字符串函数
  4. Linux日志文件总管——logrotate
  5. android 相对布局_【学习】安卓212相对布局的练习含代码版
  6. 【AI视野·今日CV 计算机视觉论文速览 第227期】Fri, 25 Jun 2021
  7. bzoj3993 [SDOI2015]星际战争 二分答案+网络流检验
  8. 【Yarn】yarn local dirs的管理实现
  9. python求矩阵维度必须一致_python数据分析(二)--Numpy
  10. LeetCode 1035 不相交的线
  11. 一年成为ai算法工程师_我作为一名数据科学研究员所学到的东西在一年内成为了AI领导者...
  12. mysql pt kill脚本_mysql 案例 ~ pt-kill工具的使用
  13. 欧拉角Yaw、Pitch、Roll
  14. html表格内容自动换行符,html表格内容自动换行
  15. 全国计算机一级证书重点知识,全国计算机一级
  16. ctf实验吧writeup
  17. Qt5.6.1如何使用qpf2字体
  18. 基于云原生的大数据产品前端实践 | 第七期图文直播文字回放
  19. HTML Responsive Web Page
  20. “收藏本站” 的代码

热门文章

  1. TML 元素和有效 DOCTYPES
  2. php 发送网络命令,通过网络服务器运行时无法发送邮件,但能够从命令行发送相同的PHP脚本...
  3. win10 软件推荐
  4. c#连接mysql数据库查询语句_C#连接MySQL数据库(增删改查)
  5. matlab上打不上字,请教一下高手 我的M文件为什么打印不出文字
  6. Payroll工资单中英文对照明细
  7. 现在进行时的被动语态
  8. 微信公众号消息与事件处理机制
  9. 一个简单的连续变焦红外镜头的从零开始的设计过程(zemax)(一)
  10. Premiere Pro 2022 for Mac(PR2022)