前言

大家好啊,我是汤圆,明天给大家带来的是《Java中的IO流-入门篇》,心愿对大家有帮忙,谢谢

因为Java的IO类有很多,这就导致我刚开始学的时候,感觉很乱,每次用到都是上网搜,后果每次用完就忘;

起初沉下心去看书学习,才明确都是有法则的;

这里先做个简略的介绍,作为入门级教程,前面还有很多要学习的,有空再整顿吧。

简介

文件IO流,次要有两种形式

  1. 字节流:基于一般的Java对象,仅实用于Java程序之间的读写
  2. 字符流:基于一般的文本字符串,不仅实用于Java程序之间的读写,也实用于Java程序和其余语言程序之间的读写

本例中用到的相干类如下:

所有的读写操作都是针对内存而言的,因为程序就是运行内存

读操作就是从磁盘文件或网络流读到内存,对于内存而言就是Input

写操作就是从内存写到磁盘文件或网络流,对于内存而言就是Output

上面别离介绍这两种形式

字节流:基于一般的Java对象

字节流的读和写都是基于Java程序而言,比方在一个机器上的Java程序写入一个对象到文件,而后传输到另一个机器上的Java程序去读取文件中的对象

写入Java对象时,会先将Java对象序列化(对象转为字节),而后写入

读取Java对象时,会先将Java对象反序列化(字节转为对象),而后读取

写对象

将对象写入到文件中,须要先把对象序列化,而后再把序列化后的字节写入到文件中;

序列化就是将对象的属性信息转为一系列字节(不包含transient 类型的属性,上面会介绍)

大略流程如下所示:

读对象

将对象从文件中读出来,须要先反序列化,而后再转为对应的Java对象,并复原对象属性值

反序列化就是将一系列字节转为实在的对象实例(不包含transient类型的属性)

大略流程如下所示:

transient

该修饰符 字面意思是刹时的,短暂的

用在对象的属性上,就示意这个属性是临时无效的,等序列化的时候会生效

在反序列化的时候,这个属性就会为null(如果属性是对象援用)或根底类型的默认值(如果属性是根底类型)

比方明码等比拟隐衷的属性,咱们就能够设置为transient,这样就不会在传输过程中被被人拦挡,从而破解出明码

代码

public class ObjectIoDemo {    public static void main(String[] args) throws IOException, ClassNotFoundException {        InnerObject object1 = new InnerObject(10);        String filename = "object.bin";        writeObjectFun(filename, object1);        InnerObject objectReturn = (InnerObject) readObjectFun(filename);        System.out.println(objectReturn);    }    // 写对象 到指定文件    public static void writeObjectFun(String filename, Object o) throws IOException {        FileOutputStream fileOutputStream = new FileOutputStream(filename);        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);        objectOutputStream.writeObject(o);        // 敞开流,fileOutputStream会一并敞开        objectOutputStream.close();    }    // 读对象 从指定文件    public static Object readObjectFun(String filename) throws IOException, ClassNotFoundException {        FileInputStream fileInputStream = new FileInputStream(filename);        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);        Object o = objectInputStream.readObject();        // 敞开流,fileInputStream会一并敞开        objectInputStream.close();        return o;    }}class InnerObject implements Serializable{    @Override    public String toString() {        return "InnerObject{" +                "num=" + num +                '}';    }    public InnerObject(int num) {        this.num = num;    }    public int getNum() {        return num;    }    public void setNum(int num) {        this.num = num;    }    private int num;}

如果要写入的Java对象没有序列化,则会报错如下

Exception in thread "main" java.io.NotSerializableException: com.jalon.basic.io.InnerObject    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)    at com.jalon.basic.io.ObjectIoDemo.writeObjectFun(ObjectIoDemo.java:28)    at com.jalon.basic.io.ObjectIoDemo.main(ObjectIoDemo.java:19)

字符流:基于一般文本字符串

字符流写入到文件中的数据,是作为通用文本数据来解决的,这样Java程序和其余程序都能够去读写这个文件

写文本

大抵流程如下:

读文本

大抵流程如下:

BufferedReader和BufferedWriter的作用

为什么要用缓冲区呢?间接用FileReader和FileWriter不也能够吗?

如果间接用FileWriterFileReader是能够运行,只不过效率会比拟低,因为每一次的读写都是针对磁盘操作的;

BufferedWriterBufferedReader这两个缓冲区能够缩小磁盘的读写次数;

BufferedReader:程序能够从磁盘一次性读很多数据到缓冲区,再从缓冲区一次次读,等缓冲区为空时再去磁盘读;

BufferedWriter:程序能够写屡次到缓冲区,等缓存区满了再一次性写入到磁盘中

代码

public class TextIoDemo {    public static void main(String[] args) throws IOException {        String filename = "string.txt";        writeString(filename, "hello world");        String res = readString(filename);        System.out.println(res);    }    // 写字符串到指定文件    public static void writeString(String filename, String content) throws IOException {        FileWriter fileWriter = new FileWriter(filename);        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);        bufferedWriter.write(content);        bufferedWriter.close();    }    // 从指定文件读取字符串    public static String readString(String filename) throws IOException {        FileReader fileReader = new FileReader(filename);        BufferedReader bufferedReader = new BufferedReader(fileReader);        String line = "";        StringBuilder stringBuilder = new StringBuilder();        while ((line=bufferedReader.readLine())!=null){            stringBuilder.append(line);        }        bufferedReader.close();        return stringBuilder.toString();    }}

总结

IO流分为字节流字符流

如果读写两边都是Java程序,则举荐用字节流,序列化和反序列化很不便

如果一边是Java程序,另一边是其余语言的程序,则举荐用字符流,读写的内容都是文本格式,不便解析

下面只是列出了个别读写类,Java中读写类还有很多,大家感兴趣的能够去java.io下查看

参考

  1. 《Head First Java》(第二版)
  2. 《Java 核心技术卷一》(第十版)
  3. 《Java 编程思维》(第四版)

后记

最初,感激大家的观看,谢谢