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能够在现存的处理单字节的系统上正确传输。


相关文章
|
30天前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
65 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
1月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
32 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
70 1
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
23天前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
39 0
|
2月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
30天前
|
安全 Java 编译器
Java基础-知识点(二)
Java基础-知识点(二)
12 0
|
30天前
|
存储 缓存 安全
Java基础-知识点(一)
Java基础-知识点(一)
16 0
|
1月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
35 0
|
2月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
下一篇
无影云桌面