缓冲输出流写出数据时的缓冲区问题

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

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对象(前提是这组字节是一个对象序列化得到的字节)

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

package io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;/*** 对象流* java.io.ObjectOutputStream和ObjectInputSteam* 对象流是一对高级流,在流连接中的作用是进行对象的序列化与反序列化** 对象序列化:将一个java对象按照其结构转换为一组字节的过程* 对象反序列化:将一组字节还原为java对象(前提是这组字节是一个对象序列化得到的字节)*/
public class OOSDemo {public static void main(String[] args) throws IOException {//将一个Person对象写入文件person.objString name = "苍老师";int age = 18;String gender = "女";String[] otherInfo = {"是一名台词不多的演员","来自岛国","爱好写大字","广大男性同胞的启蒙老师"};Person p = new Person(name,age,gender,otherInfo);System.out.println(p);FileOutputStream fos = new FileOutputStream("person.obj");ObjectOutputStream oos = new ObjectOutputStream(fos);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 {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

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

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

package io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;/*** 字符流* java将流按照读写单位划分为字节流与字符流.* java.io.InputStream和OutputStream是所有字节流的超类* 而java.io.Reader和Writer则是所有字符流的超类,它们是平级关系.** Reader和Writer是两个抽象类,里面规定了所有字符流都必须具备的读写字符的相关方法.* 字符流最小读写单位为字符(char),但是底层实际还是读写字节,只是字符与字节的转换工作由* 字符流完成.** 转换流* java.io.InputStreamReader和OutputStreamWriter* 它们是字符流非常常用的一对实现类同时也是一对高级流,实际开发中我们不直接操作它们,但是* 它们在流连接中是非常重要的一环.*/
public class OSWDemo {public static void main(String[] args) throws IOException {//向文件osw.txt中写入文字FileOutputStream fos = new FileOutputStream("osw.txt");OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");osw.write("我可以接受你的所有,所有小脾气.");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.PrintWriter

java.io.BufferedWriter和BufferedReader

缓冲字符流内部也有一个缓冲区,读写文本数据以块读写形式加快效率.并且缓冲流有一个特别的功能:可以按行读写文本数据.

java.io.PrintWriter具有自动行刷新的缓冲字符输出流,实际开发中更常用.它内部总是会自动连接BufferedWriter作为块写加速使用.

package io;import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;/*** 缓冲字符流* 缓冲字符流是一对高级流,在流连接中的作用是提高读写文本数据的效率,并且* 可以安行读写字符串.* java.io.BufferedReader和BufferedWriter** 实际开发中缓冲字符输出流我们更常用的是PrintWriter,具有自动行刷新功能* 的缓冲字符输出流,其内部总是连接BufferedWriter作为缓冲加速使用.*/
public class PWDemo1 {public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {/*PrintWriter提供了对文件操作的构造方法:PrintWriter(String path)PrintWriter(File file)*///向文件中写入字符串PrintWriter pw = new PrintWriter("pw.txt","UTF-8");pw.println("我看过沙漠下暴雨");pw.println("看过大海亲吻鲨鱼");pw.println("看过黄昏追逐黎明");pw.println("没看过你");System.out.println("写出完毕!");pw.close();}
}

在流链接中使用PW

package io;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** 在流连接中使用PW*/
public class PWDemo2 {public static void main(String[] args) throws FileNotFoundException {//文件字节输出流(是一个低级流),向文件中写入字节数据FileOutputStream fos = new FileOutputStream("pw2.txt",true);//转换输出流(是一个高级流,且是一个字符流)。1:衔接字符与字节流 2:将写出的字符转换为字节OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);//缓冲输出流(是一个高级流,且是一个字符流)。块写文本数据加速BufferedWriter bw = new BufferedWriter(osw);//具有自动行刷新的缓冲字符输出流PrintWriter pw = new PrintWriter(bw);//完成简易记事本。控制台输入的每行字符串都按行写入文件。单独输入exit时退出。Scanner scanner = new Scanner(System.in);while(true){String line = scanner.nextLine();if("exit".equalsIgnoreCase(line)){break;}pw.println(line);}pw.close();}
}

PrintWriter的自动行刷新功能

如果实例化PW时第一个参数传入的是一个流,则此时可以再传入一个boolean型的参数,此值为true时就打开了自动行刷新功能。 即: 每当我们用PW的println方法写出一行字符串后会自动flush.

package io;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** 在流连接中使用PW*/
public class PWDemo2 {public static void main(String[] args) throws FileNotFoundException {//文件字节输出流(是一个低级流),向文件中写入字节数据FileOutputStream fos = new FileOutputStream("pw2.txt",true);//转换输出流(是一个高级流,且是一个字符流)。1:衔接字符与字节流 2:将写出的字符转换为字节OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);//缓冲输出流(是一个高级流,且是一个字符流)。块写文本数据加速BufferedWriter bw = new BufferedWriter(osw);//具有自动行刷新的缓冲字符输出流/*PrintWriter提供的构造器中,当第一个参数为一个流时,就支持再传入一个boolean型的参数表示是否自动行刷新。当该值为true时则打开了自动行刷新功能。这意味着每当我们调用println方法后会自动flush一次。*/PrintWriter pw = new PrintWriter(bw,true);//完成简易记事本。控制台输入的每行字符串都按行写入文件。单独输入exit时退出。Scanner scanner = new Scanner(System.in);while(true){String line = scanner.nextLine();if("exit".equalsIgnoreCase(line)){break;}pw.println(line);}pw.close();}
}

JAVA IO(续)相关推荐

  1. java.io.StreamCorruptedException: invalid type code: AC错误的解决方法

    问题描述: 在向一个文件写入可序列化对象时,每次只想向文件的末尾添加一个可序列化的对象,于是使用了FileOutputStream(文件名,true)间接的构建了ObjectOutputStream流 ...

  2. Java IO流 详解(字节流、字符流、输入流、输出流、刷新)

    一.IO流概述 I:Input输入  从其他存储设备[读]数据到内存中  输入过程         O:OutPut输出  从内存中[写]数据到其他存储设备  输出过程 二.IO流分类 1.根据数据的 ...

  3. java IO(二)—— 字符输入输出流

    javo. io. Reader:字符输入流 是字符输入流的最顶层的父类,定义了-些共性的成员方法,是一个抽象类 共性的成员方法: int read() 读取单个字符并返回. int read(cha ...

  4. JAVA IO必备知识

    目录 一.什么是IO 二.IO的分类 三.字节流 1.字节传一切 2.字节输入流InputStream 3.FileInputStream类 4.字节输出流OutputStream 5.FileOut ...

  5. Java(2)-Java IO输入输出流

    一.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...

  6. 一篇文章了解 Java IO 流

    一:IO 流的概述 1. 什么是 IO 流? 存储和读取数据的解决方法 I:input O:output 流:像水流一样传输数据 2. IO 流的作用? 用于读写数据(本地文件,网络) 3. IO 流 ...

  7. Java——IO流超详细总结

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 在初学Java时,I ...

  8. Java IO 流 学习 总结

    I/O  主要是对文件进行处理, 其主要包含3个方面的内容 1 input 输入 2 out 出入 3 File 文件 Java 流的概念 流是一组有序的数据序列,流提供了一条通道程序,可以是这条通道 ...

  9. Java基础(二十七)Java IO(4)字符流(Character Stream)

    字符流用于处理字符数据的读取和写入,它以字符为单位. 一.Reader类与Writer类 1.Reader类是所有字符输入流的父类,它定义了操作字符输入流的各种方法. 2.Writer类是所有字符输出 ...

最新文章

  1. Centos7安装Miniconda及配置jupyter
  2. 规格上下限和控制上下限计算_涡街流量计选型时对测量上下限的考虑
  3. 计算机硬盘能否做u盘用怎么用,U盘能一直插在电脑上当硬盘用吗?
  4. 网页html好学嘛,javascript好学么?
  5. mysql调优_MYSQL企业常用架构与调优经验分享
  6. 计算机网络3-DNS域名解析系统
  7. 嵌入式linux和pc机的linux对照
  8. Tunnels 状压DP+BFS
  9. python 对话框开发_python文件选择对话框的操作方法
  10. 自给自足实现web网络文字游戏【追梦西游】(一)
  11. 电脑怎么打印pdf文件,电脑中保存的pdf文件怎么打印
  12. YUV420图像旋转
  13. 导入自己写好的python包
  14. linux_shell_命令行查单词/shell英文词典工具包(sdcv/dict/trans/wd)
  15. StampedLock(印戳锁)详解
  16. ppt里面如何插入表格
  17. 单引号、双引号、三引号用法
  18. 编辑视频贴纸软件_12款自媒体视频剪辑制作软件,爆款内容必备神器!
  19. VGG16系列IV: 参数计算
  20. 如何自动识别视频语音内容并生成字幕

热门文章

  1. android悬浮窗状态下的点击、滑动
  2. 嵌入式软硬件协同设计的过程
  3. Kong网关之蓝绿部署和金丝雀发布
  4. 计算机需要学大学物理吗,计算机系要学大学物理吗?
  5. 常用的地图坐标系及它们之间的转换
  6. Vue3中的Vue Router初探
  7. 阿里云盘 Mac 客户端测试版 v2.1.8
  8. android9 人脸解锁,小米MIUI 9上线后新增功能盘点:人脸解锁最实用
  9. ubuntu 系统使用过程中发现桌面突然放大,屏幕跟着鼠标走
  10. Java使用ffmpeg音视频分离