当前位置: 首页 > news >正文

IO流学习

思维图

在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/OutputStreamReader/WriterChannel/Buffer
适用场景图片、视频等二进制文件文本文件高并发、非阻塞IO
性能优化缓冲流(如 BufferedInputStream缓冲流(如 BufferedReader基于缓冲区和通道

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

http://www.dtcms.com/a/99984.html

相关文章:

  • 蓝桥云课 飞机降落
  • 【CSS】解决因float而导致的父类塌陷问题
  • 【云原生】Keycloak认证登录Grafana
  • 算法-贪心算法
  • Attention is All you Need阅读笔记
  • 使用 uv 管理 Python 项目
  • 摄像头视频信号在 WEB 端的显示和管理:技术与实现步骤
  • AI 的出现是否能替代 IT 从业者?
  • C语言基础(十)---指针基础
  • C++学习之路:指针基础
  • GMap.NET + WPF:构建高性能 ADS-B 航空器追踪平台
  • 【Golang】第十弹----单元测试、go协程和管道
  • 《三极管侦探社:神秘信号放大案》
  • LPDDR(Low Power Double Data Rate)详解
  • J2EE框架技术 第四章 J2EE的IOC
  • 19840 Dijkstra求最短路2
  • 文件上传存储安全OSS 对象分站解析安全解码还原目录执行
  • React编程的核心概念:数据流与观察者模式
  • POSIX 和 System V IPC的区别
  • 微信小程序(下)
  • 02_MySQL安装及配置
  • 去中心化金融的基石——以太坊
  • OSPF协议(1)
  • 海洋大地测量基准与水下导航系列之七我国海洋水下定位装备发展现状(下)
  • 耘想WinNAS:重新定义Windows电脑的存储革命
  • 一文速通Python并行计算:05 Python多线程编程-线程的定时运行
  • 查看达梦数据库对象
  • 信号与系统(郑君里)第一章-绪论 1-24 课后习题解答
  • C++学习之Linux文件编译、调试及库制作
  • 【AI论文】LeX-Art:通过可扩展的高质量数据合成重新思考文本生成