JAVA中的IO操作

一、IO基础

1、什么是IO

IO,即 Input/Output,翻译过来就是输入输出 。在 Java 编程中,它是程序与外部世界进行数据交互的关键方式。简单来说,输入就是程序从外部获取数据,比如从文件中读取内容、接收网络传来的数据;输出则是程序将数据发送到外部,像将数据写入文件、向网络另一端发送数据。

打个比方,我们日常使用的手机,当我们从相册中打开一张照片时,照片的数据从手机存储设备进入到手机应用程序,这就类似于 Java 程序中的输入操作;而当我们拍摄一张新照片并保存到相册时,照片的数据从手机相机应用程序保存到手机存储设备,这就类似于 Java 程序中的输出操作。在 Java 世界里,IO 操作让程序能够与文件系统、网络、控制台等外部环境进行数据的交换,从而实现各种各样的功能。

2、JavaIO本质是在解决什么问题

Java IO 本质就干三件事:
读文件
写文件
网络数据传输(HTTP / Socket)

二、IO核心概念

1、流的概念

在 Java IO 中,流(Stream)是一个非常重要的概念。可以把流想象成一条数据传输的通道,数据就像水流一样在这个通道中流动。它具有方向性,数据从数据源流向程序(输入流),或者从程序流向数据目的地(输出流)。并且,流中的数据是按顺序依次传输的,就像水流是依次流淌一样 。数据在流中是以字节(byte)或者字符(char)为单位进行传输的。例如,当从一个文本文件中读取数据时,数据会以字节或者字符的形式通过输入流进入程序;当向文件写入数据时,数据会以字节或字符的形式通过输出流从程序流向文件。

2、输入流(InputStream)

用于从外部数据源读取数据到程序中。在 Java 中,所有输入流的基类是InputStream(字节输入流)和Reader(字符输入流) 。例如,当我们想要读取一个文本文件的内容时,可以使用FileInputStream(InputStream的子类)或者FileReader(Reader的子类)。

就是:把数据读进来

比如:读文件、读接口返回的数据、读图片、读前端上传的文件

3、输出流(OutputStream)

用于将程序中的数据写入到外部数据目的地。Java 中所有输出流的基类是OutputStream(字节输出流)和Writer(字符输出流) 。比如,要将一些文本内容写入文件,可以使用FileOutputStream(OutputStream的子类)或者FileWriter(Writer的子类)。以下是使用FileWriter写入文件的示例代码:

就是:把数据写出去

比如:写文件、把文件返回给前端、写日志文件、把图片保存到服务器

4、字节流

以字节(8 位)为单位处理数据,适用于处理任何类型的数据,包括二进制数据,如图片、音频、视频等 。InputStream和OutputStream是字节流的抽象基类,它们的子类如FileInputStream、FileOutputStream、ByteArrayInputStream、ByteArrayOutputStream等,广泛应用于各种字节数据的读写操作。例如,读取一张图片文件并输出其字节数据:

java 复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ByteStreamExample {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("image.jpg")) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                for (int i = 0; i < length; i++) {
                    System.out.print(buffer[i] + " ");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
5、字符流

以字符(16 位 Unicode)为单位处理数据,主要用于处理文本数据 。Reader和Writer是字符流的抽象基类,其常见子类有FileReader、FileWriter、BufferedReader、BufferedWriter等。字符流在处理文本时,会自动进行字符编码转换,方便处理不同编码格式的文本文件。比如,读取一个 UTF-8 编码的文本文件并输出内容:

复制代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class CharacterStreamExample {
    public static void main(String[] args) {
        try (Reader reader = new FileReader("text.txt");
             BufferedReader bufferedReader = new BufferedReader(reader)) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字节流和字符流的主要区别在于处理数据的单位和应用场景。字节流更通用,可以处理任何类型的数据,但在处理文本时需要手动处理字符编码问题;字符流专门用于处理文本数据,自动处理字符编码,使用起来更方便,但不适用于二进制数据的处理。

6、 按功能分类

节点流:也称为低级流,是直接与数据源或数据目的地相连的流,负责从数据源读取数据或直接将数据写入数据目的地 。例如,FileInputStream和FileOutputStream直接操作文件,ByteArrayInputStream和ByteArrayOutputStream直接操作字节数组,它们都是节点流。以FileInputStream读取文件为例:

java 复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class NodeStreamExample {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("test.txt")) {
            int data;
            while ((data = inputStream.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

处理流:也叫包装流,是在节点流的基础上进行包装,增强了流的功能,如提高读写效率、增加数据处理能力等 。处理流不能单独存在,必须连接在其他流(通常是节点流)之上。例如,BufferedInputStream和BufferedOutputStream通过缓冲机制提高了数据读写的效率,它们通常会包装FileInputStream和FileOutputStream。下面是使用BufferedInputStream包装FileInputStream来提高读取效率的示例:

java 复制代码
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ProcessingStreamExample {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("test.txt");
             BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = bufferedInputStream.read(buffer)) != -1) {
                System.out.write(buffer, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,BufferedInputStream在FileInputStream的基础上增加了缓冲区,减少了系统 I/O 操作的次数,从而提高了读取效率。处理流的存在使得 Java IO 的操作更加灵活和高效,开发者可以根据具体需求选择合适的处理流来包装节点流,实现各种复杂的数据处理功能。

三、Java IO 中常用的类

1、最基础的四个父类

这四个你要先认识,它们是所有 IO 类的"根"。

1. InputStream
作用:
按字节读取数据
适合: 图片、视频、pdf、压缩包、任意二进制数据
例子:

java 复制代码
InputStream in = new FileInputStream("a.jpg");
int b = in.read();
in.close();

理解:read() 每次读取一个字节。

2. OutputStream
作用:
按字节写出数据

例子:

java 复制代码
OutputStream out = new FileOutputStream("b.jpg");
out.write(97);
out.close();

这里 97 对应字节值,写出去后可能是字符 a

3. Reader
作用:
按字符读取数据
适合: txt、json、xml、配置文件
例子:

java 复制代码
Reader reader = new FileReader("a.txt");
int ch = reader.read();
reader.close();

4. Writer
作用:
按字符写出数据
例子:

java 复制代码
Writer writer = new FileWriter("a.txt");
writer.write("你好");
writer.close();
2、文件流:和文件直接打交道

这是最常见的一组。

1. FileInputStream
作用:
从文件中读取字节

**例子:**读取图片

java 复制代码
FileInputStream in = new FileInputStream("d:/test/a.jpg");
byte[] buf = new byte[1024];
int len;

while ((len = in.read(buf)) != -1) {
    System.out.println("本次读取字节数:" + len);
}

in.close();

**什么时候用:**读图片、读 pdf、读压缩包、读任意文件原始内容

2. FileOutputStream
作用:
向文件中写字节

**例子:**写文件

java 复制代码
FileOutputStream out = new FileOutputStream("d:/test/b.txt");
out.write("hello".getBytes());
out.close();

**什么时候用:**保存文件、下载文件到本地、写二进制内容

3. FileReader
作用:
从文件中读取字符

**例子:**读取文本

java 复制代码
FileReader reader = new FileReader("d:/test/a.txt");
char[] buf = new char[1024];
int len;

while ((len = reader.read(buf)) != -1) {
    System.out.print(new String(buf, 0, len));
}

reader.close();

什么时候用: 读普通文本文件、读日志文件、读配置文件
注意: FileReader 默认用系统编码,实际开发里更推荐 InputStreamReader 指定编码。

4. FileWriter
作用:
向文件中写字符

**例子:**写文本

java 复制代码
FileWriter writer = new FileWriter("d:/test/a.txt");
writer.write("第一行\n");
writer.write("第二行\n");
writer.close();

**什么时候用:**写文本文件、生成日志、输出字符串内容

3、缓冲流:提高性能

缓冲流的思想很简单:别一次只读一个字节、写一个字节,先放到内存缓冲区里,再统一处理。

1. BufferedInputStream
作用:
给字节输入流加缓冲

**例子:**读取图片

java 复制代码
BufferedInputStream bis = new BufferedInputStream(
    new FileInputStream("d:/test/a.jpg")
);

byte[] buf = new byte[1024];
int len;

while ((len = bis.read(buf)) != -1) {
    System.out.println("读取:" + len);
}

bis.close();

什么时候用:文件读操作几乎都可以加、网络输入也常加

2. BufferedOutputStream
作用:
给字节输出流加缓冲

**例子:**复制文件

java 复制代码
BufferedInputStream bis = new BufferedInputStream(
    new FileInputStream("d:/test/a.jpg")
);
BufferedOutputStream bos = new BufferedOutputStream(
    new FileOutputStream("d:/test/b.jpg")
);

byte[] buf = new byte[1024];
int len;

while ((len = bis.read(buf)) != -1) {
    bos.write(buf, 0, len);
}

bos.close();
bis.close();

什么时候用:文件复制、文件下载、大文件写出

3. BufferedReader
作用:
给字符输入流加缓冲、可以按行读取

**例子:**按行读文本

java 复制代码
BufferedInputStream bis = new BufferedInputStream(
    new FileInputStream("d:/test/a.jpg")
);
BufferedOutputStream bos = new BufferedOutputStream(
    new FileOutputStream("d:/test/b.jpg")
);

byte[] buf = new byte[1024];
int len;

while ((len = bis.read(buf)) != -1) {
    bos.write(buf, 0, len);
}

bos.close();
bis.close();

什么时候用: 读 txt、读日志、读配置文件、按行处理文本

这是文本处理里非常常用的类。

4. BufferedWriter
作用:
高效写文本

**例子:**写多行文本

java 复制代码
BufferedWriter bw = new BufferedWriter(
    new FileWriter("d:/test/a.txt")
);

bw.write("第一行");
bw.newLine();
bw.write("第二行");
bw.newLine();

bw.close();

**什么时候用:**写日志、写报表文本、写配置文件、输出多行字符串

4、转换流:处理编码问题

这两个类非常重要。

因为很多时候,底层拿到的是字节,但你要操作的是字符。

1. InputStreamReader
作用:
把字节输入流转换成字符输入流

**例子:**按 UTF-8 读取文本

java 复制代码
BufferedReader br = new BufferedReader(
    new InputStreamReader(
        new FileInputStream("d:/test/a.txt"),
        "UTF-8"
    )
);

String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}

br.close();

什么时候用: 读取中文文本、处理乱码、读取网络响应文本、读取接口返回的 JSON
理解:

FileInputStream 负责从文件取字节。
InputStreamReader 负责把字节按 UTF-8 变成字符。
BufferedReader 负责按行读。

2. OutputStreamWriter
作用:
把字符写成指定编码的字节

**例子:**按 UTF-8 写文本

java 复制代码
BufferedWriter bw = new BufferedWriter(
    new OutputStreamWriter(
        new FileOutputStream("d:/test/a.txt"),
        "UTF-8"
    )
);

bw.write("你好,Java IO");
bw.newLine();
bw.write("第二行");

bw.close();

**什么时候用:**写中文文本、导出 txt/csv、往网络里写文本内容

5、内存流:数据不进文件,直接放内存里

这个很重要,很多接口开发里会遇到。

1. ByteArrayInputStream
作用:
从内存里的 byte[] 读取数据

例子:

java 复制代码
DataOutputStream dos = new DataOutputStream(
    new FileOutputStream("d:/test/data.bin")
);

dos.writeInt(100);
dos.writeDouble(3.14);
dos.writeBoolean(true);

dos.close();

**什么时候用:**测试代码、模拟输入流、已经有 byte\[\],但下游方法要求传 InputStream

2. ByteArrayOutputStream
作用:
往内存里写字节,最后拿到完整 byte\[\]
例子:

java 复制代码
DataInputStream dis = new DataInputStream(
    new FileInputStream("d:/test/data.bin")
);

int a = dis.readInt();
double b = dis.readDouble();
boolean c = dis.readBoolean();

System.out.println(a);
System.out.println(b);
System.out.println(c);

dis.close();

**什么时候用:**拼接数据、临时缓存、文件下载前先组装内容、接口返回前先把内容写进内存,这是非常常用的内存流。

3. StringReader
作用:
把字符串当成输入流来读
例子:

java 复制代码
StringReader sr = new StringReader("abc123");
int ch;

while ((ch = sr.read()) != -1) {
    System.out.print((char) ch);
}

sr.close();

**什么时候用:**已经有字符串,但希望按 Reader 的方式处理它

4. StringWriter
作用:
把字符写到内存中的字符串里
例子:

java 复制代码
StringWriter sw = new StringWriter();
sw.write("hello");
sw.write(" java");

String result = sw.toString();
System.out.println(result);

sw.close();

什么时候用: 在内存中拼接字符串、某些模板输出、替代 StringBuilder 的流式写法

6、数据流:按基本类型读写

1. DataOutputStream
作用:
按 Java 基本类型写数据
例子:

java 复制代码
DataOutputStream dos = new DataOutputStream(
    new FileOutputStream("d:/test/data.bin")
);

dos.writeInt(100);
dos.writeDouble(3.14);
dos.writeBoolean(true);

dos.close();

2. DataInputStream
作用:
按写入顺序读取基本类型

例子:

java 复制代码
DataInputStream dis = new DataInputStream(
    new FileInputStream("d:/test/data.bin")
);

int a = dis.readInt();
double b = dis.readDouble();
boolean c = dis.readBoolean();

System.out.println(a);
System.out.println(b);
System.out.println(c);

dis.close();

什么时候用: 需要严格按类型保存和读取数据、Java 内部二进制格式处理

**注意:**读取顺序必须和写入顺序一致。

7、对象流:直接读写 Java 对象

1. ObjectOutputStream
作用:
把对象写出去
例子:

java 复制代码
import java.io.Serializable;

class User implements Serializable {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}


ObjectOutputStream oos = new ObjectOutputStream(
    new FileOutputStream("d:/test/user.obj")
);

User user = new User("张三", 20);
oos.writeObject(user);

oos.close();

2. ObjectInputStream
作用:
把对象读回来

例子:

java 复制代码
ObjectInputStream ois = new ObjectInputStream(
    new FileInputStream("d:/test/user.obj")
);

User user = (User) ois.readObject();

ois.close();

什么时候用: Java 对象持久化、Java 对象网络传输、学习序列化机制

注意: 类必须实现 Serializable

作用 常见例子
FileInputStream 读文件字节 读图片、pdf
FileOutputStream 写文件字节 保存文件
FileReader 读文件字符 读 txt
FileWriter 写文件字符 写 txt
BufferedInputStream 字节缓冲读 提高文件读取性能
BufferedOutputStream 字节缓冲写 高效复制文件
BufferedReader 字符缓冲读 按行读文本
BufferedWriter 字符缓冲写 高效写文本
InputStreamReader 字节转字符 解决乱码
OutputStreamWriter 字符转字节 指定编码输出
ByteArrayInputStream 从 byte\[\] 读 模拟输入
ByteArrayOutputStream 写到 byte\[\] 内存拼接数据
StringReader 从字符串读 把字符串当流处理
StringWriter 写到字符串 内存中拼文本
DataInputStream 读基本类型 readInt/readDouble
DataOutputStream 写基本类型 writeInt/writeDouble
ObjectInputStream 读对象 反序列化
ObjectOutputStream 写对象 序列化
PrintStream 方便输出 System.out
PrintWriter 方便写文本 println 输出文本

四、

相关推荐
Scott9999HH42 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai6 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json