在Java编程中,读取文件是一项基础且重要的操作,无论是配置文件、日志数据还是用户输入,都可能涉及文件读取,Java提供了多种文件读取方式,涵盖了从传统字节流、字符流到现代NIO(New I/O)的多种实现,开发者可以根据具体需求选择合适的方法,以下将从基础到进阶,详细解析Java中读取文件的常用方式及注意事项。

传统字节流与字符流
Java的I/O包中,InputStream和OutputStream是所有字节流的抽象基类,而Reader和Writer则是字符流的抽象基类,读取文件时,字节流适用于二进制文件(如图片、音频),字符流则适用于文本文件(如.txt、.csv),因为它能处理字符编码的转换。
字节流读取(FileInputStream)
使用FileInputStream读取文件是最直接的方式,它以字节为单位读取数据,基本步骤包括:创建FileInputStream对象、调用read()方法读取数据、关闭流资源。
try (FileInputStream fis = new FileInputStream("example.txt")) {
int byteData;
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
上述代码中,try-with-resources语句确保流在使用后自动关闭,避免资源泄漏。
字符流读取(FileReader)
对于文本文件,使用FileReader更合适,它内部使用默认字符编码(如UTF-8)将字节转换为字符,与FileInputStream类似,使用方式为:
try (FileReader fr = new FileReader("example.txt")) {
int charData;
while ((charData = fr.read()) != -1) {
System.out.print((char) charData);
}
} catch (IOException e) {
e.printStackTrace();
}
若需指定字符编码,可结合InputStreamReader使用,例如new InputStreamReader(new FileInputStream("file.txt"), "UTF-8")。

缓冲流提升读取效率
直接使用字节流或字符流读取文件时,每次read()操作都可能触发磁盘I/O,效率较低,Java提供了缓冲流(BufferedInputStream、BufferedReader),通过内部缓冲区减少I/O次数,显著提升性能。
缓冲字符流(BufferedReader)
BufferedReader是常用的文本读取类,其readLine()方法可按行读取文本,非常适合处理日志文件或配置文件,示例:
try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader的缓冲区默认大小为8192字节,可根据需求调整。
NIO(New I/O)实现高效读取
Java NIO(自Java 1.4引入)提供了基于通道(Channel)和缓冲区(Buffer)的I/O方式,相比传统I/O,它在处理大文件和高并发场景时更具优势。
使用Files和Path(Java 7+)
Java 7引入了java.nio.file包,简化了文件操作。Files类提供了静态方法,如Files.readAllLines()可直接读取文件所有行到List<String>中:

try {
List<String> lines = Files.readAllLines(Paths.get("example.txt"), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
对于大文件,Files.lines()方法返回Stream<String>,支持流式处理,避免内存溢出:
try (Stream<String> lines = Files.lines(Paths.get("example.txt"), StandardCharsets.UTF_8)) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
使用FileChannel
FileChannel是NIO中的核心类,支持文件锁定、内存映射文件等高级功能,通过FileInputStream.getChannel()可获取通道,配合ByteBuffer读取数据:
try (RandomAccessFile file = new RandomAccessFile("example.txt", "r");
FileChannel channel = file.getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (channel.read(buffer) != -1) {
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
注意事项
- 异常处理:文件操作可能抛出
FileNotFoundException或IOException,必须使用try-catch或try-with-resources处理。 - 资源关闭:确保所有流在使用后关闭,推荐使用
try-with-resources语句自动管理资源。 - 字符编码:读取文本文件时,需明确指定字符编码(如UTF-8),避免乱码问题。
- 性能选择:小文件可用传统流或
Files.readAllLines(),大文件优先使用BufferedReader或Files.lines()。
通过合理选择文件读取方式,可以高效、安全地完成Java中的文件操作,为程序开发提供坚实的数据输入支持。



















