前言

大家好啊,我是汤圆,今天给大家带来的是《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 编程思想》(第四版)

后记

最后,感谢大家的观看,谢谢

Java中的IO流 - 入门篇的更多相关文章

  1. Java中的IO流之输入流|乐字节

    亲爱的乐字节的小伙伴们,小乐又来分享Java技术文章了.上一篇写到了IO流,这篇文章着重 谈谈输入流,再下次再说输出流. 点击回顾上一篇:乐字节Java之file.IO流基础知识和操作步骤 一. 输入 ...

  2. Java中的IO流(五)

    上一篇<Java中的IO流(四)>记录了一下Properties类,此类不属于IO流,它属于集合框架.接下来说一下IO流中的其它流 一,打印流PrintStream PrintStream ...

  3. Java中的IO流(六)

    上一篇<Java中的IO流(五)>把流中的打印流PrintStream,PrintWriter,序列流SequenceInputStream以及结合之前所记录的知识点完成了文件的切割与文件 ...

  4. Java中的IO流(四)

    上一篇<Java中的IO流(三)>把IO流中的文件及目录操作的对象File类记录了一下,本篇把本不属性IO流但又和IO流有关系的一个对象作一下记录,此对象本属于集合框架里的一个子集,即Pr ...

  5. Java中的IO流(三)

    上一篇<Java中的IO流(二)>把学习Java的字符流以及转换流作了一下记录,从本篇开始将把IO流中对文件或文件夹操作的对象File类的学习进行一下记录. 一,File类的构造函数及字段 ...

  6. Java中的IO流(二)

    上一篇<Java中的IO流(一)>把学习IO流的字符流作了一下记录,本篇把字节流记录一下. 一,Java中的字节流 Java中的字节流的操作方式与字符流的操作方式大致相同,连方法名都是类似 ...

  7. Java中的IO流之输出流|乐字节

    大家好,乐字节小乐又来了.上一篇给大家带来的是:Java中的IO流之输入流|乐字节,本文将继续讲述IO流之输出流.   一.输出流 1.抽象类:OutputStream 和 Writer Output ...

  8. java中的IO流

    Java中的IO流 在之前的时候我已经接触过C#中的IO流,也就是说集中数据固化的方式之一,那么我们今天来说一下java中的IO流. 首先,我们学习IO流就是要对文件或目录进行一系列的操作,那么怎样操 ...

  9. Java中的IO流总结

    Java中的IO流总结 1. 流的继承关系,以及字节流和字符流. 2. 节点流FileOutputStream和FileInputStream和处理流BufferedInputStream和Buffe ...

随机推荐

  1. js screen size check

    js screen size check js 屏幕尺寸检测 window.screen API screen; window.screen.width; window.screen.height; ...

  2. git commit guidelines

    git-commit-guidelines AngularJS Development Setup Running Tests Coding Rules Commit Message Guidelin ...

  3. how to using js to realize notes feature on the website

    how to using js to realize notes feature on the website js & notes demos https://medium.com/brow ...

  4. npm & package.json & directories & files

    npm & package.json & directories & files package.json https://docs.npmjs.com/files/packa ...

  5. uniapp 发起网络请求

    推荐下我写的uni-http 创建http-config.js import Vue from 'vue' const BASE_URL = 'http://xxx.com'; if (process ...

  6. mysql explain type详解

    本文转载自最官方的 mysql explain type 字段解读 读了很多别人的笔记都杂乱不堪,很少有实例,什么都不如原装的好,所以当你读到我的笔记的时候如果觉得说的不明白,最好参考官方的手册. 我 ...

  7. oracle之用户

    命令都是在命令行窗口执行 创建用户 1)登陆管理员用户 sqlplus system/密码 sqlplus system/briup 注意不要以分号结尾 2)创建用户 create user 用户名 ...

  8. Vue(1)

    一:概述 Vue是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用.Vue的核心库只关心视图层,不仅易于上手,还便于与第三方库或既有项目 ...

  9. Vue学习笔记-vue-element-admin 按装报错再按装

    一  使用环境 开发系统: windows 后端IDE: PyCharm 前端IDE: VSCode 数据库: msyql,navicat 编程语言: python3.7  (Windows x86- ...

  10. js中函数调用时,对参数个数和类型没有要求

    因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java一样对其传入参数的类型进行定,也对传入参数的个数没有要求. js函数的参数与大多数其他语 ...