ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java中的IO流 - 入门篇

2021-05-12 15:31:59  阅读:130  来源: 互联网

标签:Java String 对象 filename 入门篇 IO 序列化 public


简介

文件IO流,主要有两种方式

  • 字节流:基于各种文件,包括普通文本txt,音频文件mp3,视频文件mp4等

  • 字符流:基于普通的文本字符串,比如普通文本txt等

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

在这里插入图片描述

所有的读写操作都是针对内存而言的,因为程序就是运行在内存中
读操作就是从磁盘文件或网络流读到内存,对于内存而言就是Input
写操作就是从内存写到磁盘文件或网络流,对于内存而言就是Output

下面分别介绍这两种方式

字节流

本例子,字节流中主要讲的是ObjectInputStream和ObjectOutputStream,这两个类是针对普通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不也可以吗?

如果直接用FileWriter和FileReader是可以运行,只不过效率会比较低,因为每一次的读写都是针对磁盘操作的;

而BufferedWriter和BufferedReader这两个缓冲区可以减少磁盘的读写次数;

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下查看。

标签:Java,String,对象,filename,入门篇,IO,序列化,public
来源: https://blog.csdn.net/Li_Jian_Hui_/article/details/116708590

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有