JAVA—IO流知识点总结

简介: JAVA—IO流知识点总结

一、IO流的概念

 流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出


  • IO是Input和Output的简写,也就是输入和输出的含义。
  • IO流是指读写数据时像流水一样从一端流到另外一端,因此得名为"流"。


二、流的分类

Java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。


按数据的流向不同分为:输入流和输出流

   --------->输入流:把数据从其他设备上读取到内存中的流。


                 通常以InputStream、Reader结尾


  ---------->输出流:把数据从内存中写到其他设备上的流


                 通常以OutputStream、Write结尾


按操作数据单位的不同分为:字节流和字符流

  --------->字节流:以字节为单位,读写数据的流


                 通常以InputStream、OutputStream结尾


  ---------->字符流:以字符为单位,读写数据的流


                 通常以Reader、Write结尾


根据IO流的角色不同可分为:节点流和处理流

  -------->节点流:直接从数据源或目的地读写数据


 --------->处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。


三、流的API

JAVA的IO流共涉及40多个类,实际上非常规则,都是从如下类中派生:

(抽象基类) 输入流 输出流
字节流 InputStream OutputStream
字符流 Reader Writer


四、FileReader/FileWriter使用

执行步骤:

创建读取或写出的File类的对象

2.创建输入流或者输出流

3.具体的读入或者写出的过程

    读入:read(char[] cbuffer)

    写出:write(String str) / write(char[] cbuffer,0,len)

4.关闭流资源,避免内存泄漏

注意事项:

1.涉及到了流资源的关闭操作,出现异常的话,需要使用try-catch-finally来处理异常

2.对于输入流,要求file类的对象对应的物理磁盘上的文件必须存在。否则会报

FileNotFoundException的异常。


3.对于输出流,file类的对象对应的物理磁盘上的文件可以不存在。


-----》如果文件不存在,输出过程中,会自动创建此文件,并写出数据到此文件中


-----》如果文件存在,使用FileWriter(File file)或FileWriter(File file,false)

          ------>FileWriter(File file,false):输出过程,会创建同名的文件对现有的文件进行覆盖


          ------->FileWriter(File file,true):输出过程,会在现有的文件末尾追加写出的内容


import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class FileReadWriteExample {
    public static void main(String[] args) {
        String filePath = "path/to/file.txt"; // 文件路径
 
        // 使用FileReader读取文件内容
        try (FileReader fileReader = new FileReader(filePath)) {
            int character;
            while ((character = fileReader.read()) != -1) {
                // 处理读取的字符
                System.out.print((char) character);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        // 使用FileWriter写入文件内容
        try (FileWriter fileWriter = new FileWriter(filePath)) {
            String content = "Hello, world!";
            fileWriter.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上面的代码示例中,我们首先定义了文件的路径 filePath,你需要将其替换为你要读取或写入的实际文件路径。


然后我们使用FileReader来读取文件内容。在此示例中,我们使用read()方法来一个字符一个字符地读取文件内容,并将其转换为字符类型 char 进行处理。读取的循环会一直执行直到文件的末尾(read()方法返回-1)。

接下来,我们使用FileWriter来写入文件内容。在此示例中,我们使用write()方法将字符串内容写入文件。你可以根据需要写入不同的内容。


五、基础的IO流框架

图片.png

缓冲流:缓冲流也称为处理流,对文件或者其他目标频繁的操作,效率低,性能差。缓冲流目的是提高程序读取和写出的性能。缓冲流也分为字节缓冲流(如FileInputStream与FileOutputStream)和字符缓冲流(如FileReader与FileWriter)

基本原理:

是创建流对象时候,会创建一个内置的默认大小的缓冲区数组,通过缓冲区书写.使得性能大大提升。


使用方法:


处理非文本文件的字节流:


BufferedInputStream     read(byte[] buffer)


BufferedOutputStream   write(byte[] buffer,0,len)


处理文本文件的字符流:


BufferedReader    read(char[] cBuffer) / readLine()


BufferedWriter      write(char[] cBuffer,0,len)

六、FileInputStream使用

执行步骤:

1.创建读取或写出的File类的对象

2.创建输入流或者输出流

3.具体的读入或者写出的过程

    读入:read(byte[] buffer)

    写出:write(byte[] buffer,0,len)

4.关闭流资源,避免内存泄漏

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class FileReadWriteExample {
    public static void main(String[] args) {
        String sourcePath = "path/to/source_file.txt";  // 源文件路径
        String destPath = "path/to/dest_file.txt";      // 目标文件路径
 
        // 使用FileInputStream读取文件内容
        try (FileInputStream fis = new FileInputStream(sourcePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                // 处理读取的数据
                // 此处示例将读取的数据直接写入目标文件中
                try (FileOutputStream fos = new FileOutputStream(destPath, true)) {
                    fos.write(buffer, 0, bytesRead);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上面的代码示例中,我们假设有一个源文件和一个目标文件,你需要将 sourcePath 和 destPath 替换为实际的文件路径。源文件将从 sourcePath 读取,然后将读取的内容写入目标文件中。


我们使用 FileInputStream 来读取文件的内容。在示例中,我们使用一个字节数组 buffer 来存储每次读取的数据。通过调用 read() 方法来读取数据,并将读取的字节数保存在 bytesRead 中。如果 read() 方法返回 -1,表示已经读取到文件末尾。


然后,我们使用 FileOutputStream 来将读取的数据写入目标文件中。我们通过调用 write() 方法将读取的数据写入文件中,写入的字节数为 bytesRead。

七、对象流的使用

ObjectOutoutStream:将内存中的对象———>磁盘中的文件、通过网络传输的数据。:序列化

ObjectInputStream:磁盘中的文件或通过网络接受的数据———>内存中的对象。:反序列化


  • 序列化是将对象转换为字节流的过程,反序列化是将字节流转换为对象的过程。
  • 序列化和反序列化需要使用相同的序列化算法,否则无法正确地进行反序列化。
  • 常见的序列化算法有JSON、XML、Protobuf、MsgPack等。
  • 序列化和反序列化的性能对系统的影响非常大,需要根据实际情况选择合适的序列化算法。
  • 在redis中,可以使用自定义的序列化算法,也可以使用redis自带的序列化算法。
  • 序列化和反序列化的过程中需要注意对象的版本兼容性问题,避免出现反序列化失败的情况。

序列化示范:

try {
    // 创建一个对象输出流
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("object.txt"));
    // 创建一个对象
    Person person = new Person("Tom", 18);
    // 将对象序列化到文件中
    out.writeObject(person);
    // 关闭输出流
    out.close();
} catch (IOException e) {
    e.printStackTrace();
}

反序列化示范:

try {
    // 创建一个对象输出流
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("object.txt"));
    // 创建一个对象
    Person person = new Person("Tom", 18);
    // 将对象序列化到文件中
    out.writeObject(person);
    // 关闭输出流
    out.close();
} catch (IOException e) {
    e.printStackTrace();
}

其中,Person类需要实现Serializable接口,示例代码如下:

public class Person implements Serializable {
    private String name;
    private int age;
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public int getAge() {
        return age;
    }
}

在使用序列化和反序列化时,需要注意以下几点:

  1. 序列化和反序列化的对象必须是可序列化的,即对象必须实现Serializable接口或Externalizable接口。
  2. 序列化和反序列化的对象的类必须存在,否则会抛出ClassNotFoundException异常。
  3. 序列化和反序列化的对象的类的serialVersionUID必须一致,否则会抛出InvalidClassException异常。
  4. 序列化和反序列化的对象的属性必须是基本类型或可序列化的类型,否则会抛出NotSerializableException异常。
  5. 序列化和反序列化的对象的属性如果是transient修饰的,则不会被序列化和反序列化。
  6. 序列化和反序列化的对象的属性如果是static修饰的,则不会被序列化和反序列化。
  7. 序列化和反序列化的对象的属性如果是final修饰的,则在序列化时会被直接写入,反序列化时不会重新赋值。
  8. 序列化和反序列化的对象的属性如果是枚举类型,则在序列化时会写入枚举常量的名称,反序列化时会根据名称获取枚举常量。
  9. 序列化和反序列化的对象的属性如果是集合类型,则需要保证集合中的元素也是可序列化的。


八、关于字符集的理解

字符集(Character set)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,就需要进行字符编码,以便计算机能够识别和存储各种文字。


  • 1.ASCII(American Standard Code for Information Interchange,美国信息互换标准编码)是基于罗马字母表的一套电脑编码系统。它是最通用的单字节编码系统,并等同于国际标准ISO 646。
  • 2.GB2312又称为GB2312-80字符集,全称为《信息交换用汉字编码字符集·基本集》,GB2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。双字节表示:两个字节中前面的字节为第一字节,后面的字节为第二字节。习惯上称第一字节为“高字节” ,而称第二字节为“低字节”。
  • 3.Big5字符集共收录13,053个中文字,Big5码使用了双字节储存方法,以两个字节来编码一个字。
  • 4.GB 18030标准采用单字节、双字节和四字节三种方式对字符编码
  • 5.Unicode 标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”
  • 6.UTF-8是Unicode的其中一个使用方式。 UTF是 Unicode Tranformation Format,即把Unicode转做某种格式的意思。UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的Unicode能够在现存的处理单字节的系统上正确传输。


相关文章
|
8天前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
7天前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
13 0
|
9天前
|
存储 安全 Java
【Java】已解决java.io.ObjectStreamException异常
【Java】已解决java.io.ObjectStreamException异常
10 1
|
16天前
|
存储 缓存 Java
Java零基础入门之IO流详解(二)
Java零基础入门之IO流详解(二)
|
5天前
|
Java 大数据 API
Java语言的核心知识点与特性
Java 是一种广泛使用的编程语言,自 1995 年发布以来,它已经成为了企业级应用开发、移动应用开发、大数据处理和云计算等领域的主流技术。
15 0
|
7天前
|
存储 并行计算 安全
Java面试题:Java内存管理、多线程与并发框架的面试题解析与知识点梳理,深入Java内存模型与垃圾回收机制,Java多线程机制与线程安全,Java并发工具包与框架的应用
Java面试题:Java内存管理、多线程与并发框架的面试题解析与知识点梳理,深入Java内存模型与垃圾回收机制,Java多线程机制与线程安全,Java并发工具包与框架的应用
12 0
|
7天前
|
Java
Java面试题:Java内存模型与并发编程知识点,解释Java中“happens-before”的关系,分析Java中的内存一致性效应(Memory Consistency Effects)及其重要性
Java面试题:Java内存模型与并发编程知识点,解释Java中“happens-before”的关系,分析Java中的内存一致性效应(Memory Consistency Effects)及其重要性
8 0
|
9天前
|
Java 程序员
【Java】已解决java.io.UnsupportedEncodingException异常
【Java】已解决java.io.UnsupportedEncodingException异常
9 0
|
9天前
|
安全 Java
【Java】已解决java.io.InterruptedIOException异常
【Java】已解决java.io.InterruptedIOException异常
9 0
|
9天前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用