Java IO流操作实战:文件读写、字节处理与字符流详解
本文将深入探讨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 (拒绝访问。) 或类似报错,通常是以下原因:
- 路径不对: IDE运行时的根目录可能与源码目录不一致。建议直接使用绝对路径(如
C:\Users\Name\Project\src\test.txt)进行测试验证后再改回相对路径。 - 文件占用: 某个编辑器或其他进程正在独占锁定该输出文件,导致无法写入。关闭相关软件即可。
- 拼写错误: 仔细检查文件名大小写(Windows不敏感但Linux敏感)及后缀名(
.txt有时会被隐藏导致误判)。
简要总结
以上关于Java输入输出流(File I/O)的各种读写技巧及代码实现的详细内容,更多关于Java IO流优化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









