Java IO流案例:使用缓冲流恢复《出师表》文章顺序

在实际的文件处理场景中,我们常常会遇到需要整理、排序文本内容的需求。本文将分享一个使用Java缓冲流对《出师表》乱序文章进行恢复的实战案例。

需求分析

现有一个《出师表》的文本文件,但文章行序被打乱。每行开头有数字编号表示正确顺序,我们需要:

  1. 读取源文件

  2. 按行首编号排序

  3. 将排序后的内容写入新文件

代码实现

java 复制代码
import java.io.*;
import java.util.*;

public class RestoreArticleOrder {
    public static void main(String[] args) {
        // 1. 定义文件路径
        String sourceFile = "chushibiao_original.txt";
        String targetFile = "chushibiao_restored.txt";
        
        try (
            // 2. 创建缓冲字符输入流
            BufferedReader br = new BufferedReader(new FileReader(sourceFile));
            // 5. 创建缓冲字符输出流
            BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile))
        ) {
            // 3. 创建List集合存储数据
            List<String> lines = new ArrayList<>();
            
            // 4. 循环读取数据
            String line;
            while ((line = br.readLine()) != null) {
                lines.add(line);
            }
            
            // 5. 按行首编号排序
            // 假设每行格式为:"1. 臣亮言..."
            lines.sort(Comparator.comparingInt(s -> {
                // 提取行首数字
                String num = s.split("\\.")[0];
                return Integer.parseInt(num);
            }));
            
            // 6. 遍历集合并写入
            for (String sortedLine : lines) {
                bw.write(sortedLine);
                bw.newLine(); // 换行
            }
            
            System.out.println("文章顺序恢复完成!");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Java IO流知识总结

一、IO流分类体系

1. 按流向分
  • 输入流:读取数据(InputStream/Reader)

  • 输出流:写入数据(OutputStream/Writer)

2. 按数据类型分
  • 字节流:处理所有类型文件

    • InputStreamFileInputStream

    • OutputStreamFileOutputStream

  • 字符流:专门处理文本文件

    • ReaderFileReader

    • WriterFileWriter

3. 按功能分
  • 节点流:直接操作数据源

  • 处理流(包装流):对节点流进行包装

二、缓冲流的优势

传统流的问题
java 复制代码
// 不使用缓冲流,每次读取一个字符
FileReader fr = new FileReader("file.txt");
int ch;
while ((ch = fr.read()) != -1) {  // 频繁IO操作
    // 处理字符
}
缓冲流的优势
java 复制代码
// 使用缓冲流,减少IO次数
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = br.readLine()) != null) {  // 一次读取一行
    // 处理整行
}

优点

  1. 减少磁盘IO次数,提高效率

  2. 提供便捷方法(如readLine()

  3. 默认缓冲区大小8KB

三、常用IO流组合方式

场景 推荐组合 说明
文本文件读取 BufferedReader + FileReader 高效读取文本
文本文件写入 BufferedWriter + FileWriter 高效写入文本
二进制文件读取 BufferedInputStream + FileInputStream 读取图片、视频
二进制文件写入 BufferedOutputStream + FileOutputStream 写入二进制数据
序列化对象 ObjectInputStream/ObjectOutputStream 对象序列化

四、最佳实践与注意事项

  1. 资源关闭

    java 复制代码
    // 使用try-with-resources确保资源关闭
    try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
        // 操作
    } catch (IOException e) {
        e.printStackTrace();
    }
  2. 异常处理

    java 复制代码
    try {
        // IO操作
    } catch (FileNotFoundException e) {
        System.out.println("文件不存在");
    } catch (IOException e) {
        System.out.println("读写异常");
    }
  3. 缓冲区刷新

    java 复制代码
    BufferedWriter bw = ...;
    bw.write("内容");
    bw.flush();  // 手动刷新缓冲区
    // 或 close()会自动flush
  4. 编码问题

    java 复制代码
    // 指定编码读取
    BufferedReader br = new BufferedReader(
        new InputStreamReader(
            new FileInputStream("file.txt"), 
            "UTF-8"
        )
    );

五、性能对比

操作类型 无缓冲流 缓冲流 提升效果
读取1MB文本 约200ms 约50ms 4倍
写入1MB文本 约150ms 约40ms 3.75倍

六、适用场景总结

  1. 缓冲流适用

    • 大文件读写

    • 文本文件处理

    • 需要逐行处理

  2. 节点流适用

    • 小文件简单操作

    • 二进制数据处理

    • 需要精细控制读写

结语

通过《出师表》顺序恢复的案例,我们实践了缓冲流的基本操作。Java IO流体系提供了丰富的选择,掌握各种流的特点和适用场景,能够帮助我们编写更高效、更健壮的文件处理程序。在实际开发中,建议优先考虑缓冲流处理文本文件,注意资源管理和异常处理,确保程序的可靠性。


关键词:Java IO流、缓冲流、BufferedReader、BufferedWriter、文件处理、字符流、性能优化

相关推荐
毕设源码-郭学长2 小时前
【开题答辩全过程】以 广告投放管理系统为例,包含答辩的问题和答案
java
纵有疾風起2 小时前
【Linux 系统开发】基础开发工具详解:自动化构建、版本控制与调试器开发实战
linux·服务器·开发语言·c++·经验分享·开源·bash
小北方城市网2 小时前
SpringBoot 集成 RabbitMQ 实战(消息队列解耦与削峰):实现高可靠异步通信
java·spring boot·python·微服务·rabbitmq·java-rabbitmq·数据库架构
java_t_t2 小时前
Maven插件apiscan介绍与使用
java·maven·api文档·maven插件
阿豪只会阿巴2 小时前
项目心得——发布者和订阅者问题解决思路
linux·开发语言·笔记·python·ubuntu·ros2
wjs20242 小时前
Java 注释
开发语言
带刺的坐椅2 小时前
FastJson2 与 SnackJson4 有什么区别?
java·jsonpath·fastjon2·snack4
linweidong2 小时前
C++如何避免 ODR(One Definition Rule)冲突?
java·jvm·c++
人道领域2 小时前
JavaWeb从入门到进阶(javaScript)
开发语言·javascript·ecmascript