IO流学习

思维图

IO流学习_第1张图片

在Java中,流是用来处理输入输出的一种机制。流的顶层父类为输入输出操作定义了一个框架,以下是关于这些顶层父类的详细信息:


Java流顶层父类概述

一、IO 流的分类

1. 按数据流向(这里理解一下)****输出流为我输出给电脑output即为OutputStream
  • 输入流:从(文件)外部(如文件、网络)读取数据到程序。
    • 示例:InputStream, Reader
  • 输出流:从程序写出数据到文件或者其他。
    • 示例:OutputStream, Writer
2. 按数据类型
  • 字节流:以 字节(8位) 为单位处理数据,适合所有类型文件(如图片、视频)。
    • 核心类:InputStreamOutputStream
  • 字符流:以 字符(16位,基于编码) 为单位处理数据,适合文本文件。(中文)
    • 核心类:ReaderWriter
3. 按功能
  • 节点流:直接操作数据源(如文件)。
    • 示例:FileInputStream, FileReader
  • 处理流(装饰流):对现有流封装,增强功能(如缓冲、转换)。
    • 示例:BufferedInputStream, InputStreamReader
    • 这里的装饰理解为将字节装饰为字符

InputStream 和 OutputStream
  • InputStream:这是所有字节输入流的超类。它定义了读取数据的基本方法,比如从输入流中读取字节和字节数组。
  • 方法
    • int read(): 从输入流中读取下一个字节的数据。
    • int read(byte[] b): 从输入流中读取一些字节,并将它们存储到指定的字节数组中。
    • void close(): 关闭输入流,并释放与该流关联的所有系统资源。
  • OutputStream:这是所有字节输出流的超类。它定义了写入数据的基本方法,比如将字节和字节数组写入输出流。
  • 方法
    • void write(int b): 将指定的字节写入输出流。
    • void write(byte[] b): 将指定的字节数组写入输出流。
    • void flush(): 刷新输出流,并强制写出所有缓冲的输出字节。
    • void close(): 关闭输出流,并释放与该流关联的所有系统资源。
Reader 和 Writer
  • Reader:这是所有字符输入流的超类。它扩展了InputStreamReader,用于读取字符数据。
  • 方法
    • int read(): 读取单个字符。
    • int read(char[] cbuf): 读取字符到一个数组中。
    • void close(): 关闭流并释放资源。
  • Writer:这是所有字符输出流的超类。它用于写入字符数据。
  • 方法
    • void write(int c): 写入单个字符。
    • void write(char[] cbuf): 写入字符数组。
    • void write(String str): 写入字符串。
    • void flush(): 刷新流。
    • void close(): 关闭流并释放资源。
      以下是一个简单的表格总结:
流类型 简介
字节流**** 以字节为单位进行数据的输入输出,适用于所有类型的数据**。**
FileInputStream 常用的文件输入流,用于从文件中读取数据。
FileOutputStream 常用的文件输出流,用于向文件中写入数据。
字符流 以字符为单位进行数据的输入输出,通常用于文本数据。
FileReader 用于读取字符文件,继承了 InputStreamReader。
FileWriter 用于写入字符文件,继承了 OutputStreamWriter。
数组流 针对内存中的数据流进行操作,也称为内存流。
ByteArrayInputStream 从内存中读取数据的输入流。
ByteArrayOutputStream 向内存中写入数据的输出流。
管道流 用于线程之间的数据传递。
PipedInputStream 管道输入流,用于从一个线程读取数据。
PipedOutputStream 管道输出流,用于向另一个线程写入数据。
基本数据类型流 用于输入输出基本数据类型。
DataInputStream 用于读取Java基本数据类型的数据。
DataOutputStream 用于写入Java基本数据类型的数据。
缓冲流 提供缓冲机制,提高I/O效率。
BufferedInputStream 带缓冲的字节输入流,提高读取效率。
BufferedOutputStream 带缓冲的字节输出流,提高写入效率。
BufferedReader 带缓冲的字符输入流,提高读取效率。
BufferedWriter 带缓冲的字符输出流,提高写入效率。
打印流 用于格式化输出数据。
PrintStream 打印流,可以打印数据到控制台或文件。
PrintWriter 打印流,可以打印数据到控制台或文件,并支持格式化。
对象序列化/反序列化流 用于对象的序列化和反序列化。
ObjectOutputStream 用于将对象序列化到输出流中。
ObjectInputStream 用于从输入流中反序列化对象。
转换流 用于字节流和字符流之间的转换。
InputStreamReader 用于将字节流转换为字符流。
OutputStreamWriter 用于将字符流转换为字节流。
其他 其他特殊用途的流。
RandomAccessFile 可以对文件进行随机访问的类,支持文件的读写操作。

1.什么是流 (Stream)?

一般来说关于流的特性有下面几点:

  • 先进先出:最先写入输出流的数据最先被输入流读取到。
  • 顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile除外)
  • 只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

二、核心类与用法

1. 字节流(Byte Streams)
  • 读取文件FileInputStream
try (InputStream is = new FileInputStream("test.txt")) {
    int data;
    while ((data = is.read()) != -1) { // 逐字节读取
        System.out.print((char) data);
    }
} catch (IOException e) {
    e.printStackTrace();
}
  • 写入文件FileOutputStream
try (OutputStream os = new FileOutputStream("output.txt")) {
    String text = "Hello, IO Stream!";
    os.write(text.getBytes()); // 字节数组写入
} catch (IOException e) {
    e.printStackTrace();
}
2. 字符流(Character Streams)
  • 读取文本文件FileReader + BufferedReader
try (Reader reader = new FileReader("test.txt");
     BufferedReader br = new BufferedReader(reader)) {
    String line;
    while ((line = br.readLine()) != null) { // 逐行读取
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}
  • 写入文本文件FileWriter + BufferedWriter
try (Writer writer = new FileWriter("output.txt");
     BufferedWriter bw = new BufferedWriter(writer)) {
    bw.write("Hello, 字符流!");
    bw.newLine(); // 写入换行符
} catch (IOException e) {
    e.printStackTrace();
}
3. 缓冲流(Buffered Streams)
  • 提升IO效率,减少频繁读写磁盘次数。
// 字节缓冲流
try (InputStream is = new BufferedInputStream(new FileInputStream("largefile.bin"));
     OutputStream os = new BufferedOutputStream(new FileOutputStream("copy.bin"))) {
    byte[] buffer = new byte[1024];
    int len;
    while ((len = is.read(buffer)) != -1) {
        os.write(buffer, 0, len);
    }
}

// 字符缓冲流
try (BufferedReader br = new BufferedReader(new FileReader("text.txt"));
     BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"))) {
    // 逐行读写
}
4. 转换流(字节 字符)
  • 解决字节流与字符流的转换,指定编码(如UTF-8)。
// 字节流 → 字符流(按UTF-8读取)
try (InputStreamReader isr = new InputStreamReader(
         new FileInputStream("data.txt"), StandardCharsets.UTF_8)) {
    // 使用字符流操作
}

// 字符流 → 字节流(按GBK写入)
try (OutputStreamWriter osw = new OutputStreamWriter(
         new FileOutputStream("data.txt"), "GBK")) {
    osw.write("中文内容");
}


三、Java NIO(New IO)****这里是AI生成不理解后续慢慢学习

Java 1.4 引入的 NIOjava.nio 包),支持非阻塞IO和通道(Channel)模型,适合高并发场景。

核心组件
  • Buffer:数据容器(如 ByteBuffer)。
  • Channel:双向数据传输通道(如 FileChannel, SocketChannel)。
  • Selector:多路复用,监控多个通道的事件。
示例:文件复制(NIO)
try (FileChannel src = FileChannel.open(Paths.get("src.txt"), StandardOpenOption.READ);
     FileChannel dest = FileChannel.open(Paths.get("dest.txt"), 
         StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (src.read(buffer) != -1) {
        buffer.flip(); // 切换为读模式
        dest.write(buffer);
        buffer.clear(); // 清空缓冲区,切换为写模式
    }
}

四、最佳实践与常见问题

  1. 始终关闭流
    • 使用 try-with-resources(Java 7+)自动关闭资源,避免内存泄漏。
try (InputStream is = new FileInputStream("file.txt")) {
    // 操作流
} // 自动调用 is.close()
  1. 选择正确的流类型
    • 文本文件 → 字符流(避免乱码)。
    • 二进制文件(如图片) → 字节流。
  2. 优先使用缓冲流
    • 减少IO次数,显著提升性能(尤其是大文件)。
  3. 处理大文件
    • 分块读写(如 byte[8192]),避免一次性加载到内存。
  4. 编码问题
    • 明确指定字符编码(如 StandardCharsets.UTF_8),避免跨平台乱码。

五、总结对比

类别 字节流 字符流 NIO
数据单位 字节(8位) 字符(16位,带编码) 块(Buffer)
核心类 InputStream/OutputStream Reader/Writer Channel/Buffer
适用场景 图片、视频等二进制文件 文本文件 高并发、非阻塞IO
性能优化 缓冲流(如 BufferedInputStream 缓冲流(如 BufferedReader 基于缓冲区和通道

掌握 IO 流是 Java 开发的基础技能,合理选择流类型和优化方式,可以大幅提升程序效率和稳定性!

你可能感兴趣的:(java学习,学习,java,开发语言)