Java IO流操作实战:文件读写、字节处理与字符流详解

认真发呆
认真发呆
发布时间:2026-10-13 | 5人浏览过
原创

本文将深入探讨Java输入输出流(IO)的常见应用场景,通过五个具体的代码实例,详细讲解如何读取和写入文件、处理字节流与字符流以及处理键盘输入。

结果或目标

在Java应用开发中,处理外部数据源是基础且核心的能力。无论是读取配置文件、生成日志文件还是处理用户上传的数据,都离不开对Java IO流的熟练运用。本文将展示五种典型的文件I/O场景及其对应的解决方案。

准备条件

在进行以下实验前,请确保您的开发环境满足以下条件:

  • JDK 1.8或以上版本已安装并配置完毕。
  • 使用IDE(如IntelliJ IDEA或Eclipse)创建一个Java项目,包名统一设置为 src。
  • 关键准备:为便于测试,请先在项目根目录下的 src 文件夹中手动创建一个名为 test.txt 的空文件或包含少量内容的文本文档。若无此文件,后续代码执行时将抛出 FileNotFoundException。

真实操作顺序

第1步:实现文件的顺序读取与错误处理

目的: 尝试读取指定路径的文件内容并打印到控制台,若文件不存在则给出明确提示。

入口: 新建Java类 Test.java。

动作: 导入必要的 java.io 包,使用 FileReader 逐个字符地读取文件。由于读取单个字符效率较低,这里主要演示最基础的字节读取方式 read(),当返回值等于 -1 时代表读到了文件末尾。

package src;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        // 指定相对路径,确保文件存在于项目中
        File f = new File("src\\test.txt");
        try {
            FileReader fr = new FileReader(f);
            int m;
            // 循环读取直到返回-1(文件结束标志)
            while((m=fr.read()) != -1) {
                System.out.print((char)(m));
            }
            fr.close(); // 记得关闭资源
        } catch (FileNotFoundException e) {
            System.err.println("错误:找不到指定文件!");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("错误:读取文件时发生IO异常!");
            e.printStackTrace();
        }
    }
}

第2步:基于字节流的文件复制

目的: 从当前目录下读取一个二进制/文本文件的前80个字节,并将其写入到另一个文件中。

入口: 确保目录下存在 fin.txt。

动作: 使用 FileInputStream 作为输入端,FileOutputStream 作为输出端。定义一个固定大小的字节缓冲区进行数据传输。特别注意区分输入流变量和输出流变量的命名,避免覆盖对象引用。

package src;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestCopy {
    public static void main(String[] args) {
        File fin = new File("src\\fin.txt");
        File fout = new File("src\\fout.txt");
        
        try {
            // 分别创建输入流和输出流对象
            FileInputStream fis = new FileInputStream(fin);
            FileOutputStream fos = new FileOutputStream(fout);
            
            byte[] buffer = new byte[80]; // 定义80字节的缓冲数组
            int bytesRead = fis.read(buffer); // 实际读取到的字节数可能小于80
            
            if(bytesRead > 0) {
                fos.write(buffer, 0, bytesRead); // 将有效字节写出
            }
            
            // 务必按顺序关闭流,先开后关
            fis.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第3步:添加行号的文本文件转换

目的: 读取现有文本文件,逐行读取并在每行内容前添加序号(从1开始),最后保存为新文件。

入口: 使用带有缓冲区的 BufferedReader 提升读取效率。

动作: 遍历每一行字符串,拼接行号。调用 flush() 强制刷新缓冲区以确保所有数据被真正写入磁盘。

package src;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestLineNumbers {
    public static void main(String[] args) {
        File fin = new File("src\\fin.txt");
        File fout = new File("src\\output_with_numbers.txt");
        
        try {
            // 建立带缓冲的字符流通道
            BufferedReader br = new BufferedReader(new FileReader(fin));
            BufferedWriter bw = new BufferedWriter(new FileWriter(fout));
            
            String line;
            int lineNumber = 1;
            // readLine() 在没有更多行时返回 null
            while((line = br.readLine()) != null){
                bw.write(lineNumber + ", " + line); // 拼接行号
                bw.newLine(); // 写入系统特定的换行符
                lineNumber++;
            }
            bw.flush(); // 刷新缓冲区
            
            br.close();
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第4步:捕获键盘输入并重定向至文件

目的: 接收用户在控制台的键盘输入,将其实时写入本地文本文件,支持以特定命令(如“quit”)终止程序。

入口: 使用 Scanner 获取标准输入。

动作: 持续读取每一行的用户输入。如果输入内容不是结束指令,则追加写入文件;如果是结束指令,跳出循环并安全关闭文件句柄。

package src;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class TestInputCapture {
    public static void main(String[] args) {
        File output = new File("src\\input_record.txt");
        try {
            FileWriter fw = new FileWriter(output);
            Scanner scanner = new Scanner(System.in);
            String input;
            
            System.out.println("请输入内容 (输入 quit 退出): ");
            while(true) {
                input = scanner.nextLine();
                if(input.equals("quit")) {
                    break; // 发现结束标记,跳出循环
                }
                fw.write(input + "\n"); // 记录内容并换行
            }
            fw.close();
            System.out.println("输入已保存至文件。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第5步:格式化非结构化文本的输出

目的: 处理没有换行符的纯文本(如长段落中文),强制每满40个字符就进行一次人工换行输出,以适应窄屏显示。

入口: 针对 FileReader 的底层机制进行操作。

动作: 利用字符数组批量读取。每次读取后判断读取到的实际长度,根据需要进行截断或补全换行符。

package src;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestFormatOutput {
    public static void main(String[] args) {
        File fin = new File("src\\fin.txt");
        File fout = new File("src\\formatted.txt");
        
        try {
            FileReader fr = new FileReader(fin);
            FileWriter fw = new FileWriter(fout);
            
            char[] buffer = new char[40]; // 设定每行容量
            int len;
            while((len = fr.read(buffer)) != -1) {
                if(len == 40) {
                    // 读满一行,直接写出
                    fw.write(buffer);
                    fw.write("\n"); // 添加换行符
                } else {
                    // 读到尾部不足40个字符,只写出有效部分
                    fw.write(buffer, 0, len);
                    fw.write("\n"); // 最后一行也换行
                }
            }
            
            fr.close();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

完成判断

操作成功的标志是:项目工作区内的 src 文件夹中生成了对应的输出文件(如 fout.txt, input_record.txt 等),且打开这些文件查看内容符合预期(包括正确的数据流向、准确的行号排序以及设定的字符长度限制)。

原文有依据的排错

如果在运行过程中遇到 java.io.FileNotFoundException: src\xxx.txt (拒绝访问。) 或类似报错,通常是以下原因:

  1. 路径不对: IDE运行时的根目录可能与源码目录不一致。建议直接使用绝对路径(如 C:\Users\Name\Project\src\test.txt)进行测试验证后再改回相对路径。
  2. 文件占用: 某个编辑器或其他进程正在独占锁定该输出文件,导致无法写入。关闭相关软件即可。
  3. 拼写错误: 仔细检查文件名大小写(Windows不敏感但Linux敏感)及后缀名(.txt 有时会被隐藏导致误判)。

简要总结

以上关于Java输入输出流(File I/O)的各种读写技巧及代码实现的详细内容,更多关于Java IO流优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表