[1. 认识文件系统](#1. 认识文件系统)
[1.1 文件的基本概念](#1.1 文件的基本概念)
[1.2 树形结构与目录](#1.2 树形结构与目录)
[1.3 文件路径与分隔符](#1.3 文件路径与分隔符)
[1.4 文件类型与权限](#1.4 文件类型与权限)
[1.5 "万物皆文件" 理念](#1.5 "万物皆文件" 理念)
[2. Java 中操作文件:File 类详解](#2. Java 中操作文件:File 类详解)
[2.1 File 类概述](#2.1 File 类概述)
[2.2 File 类核心属性与构造方法](#2.2 File 类核心属性与构造方法)
[2.3 File 类常用方法](#2.3 File 类常用方法)
[2.4 代码示例:文件与目录的基本操作](#2.4 代码示例:文件与目录的基本操作)
[示例 1:路径相关方法的差异](#示例 1:路径相关方法的差异)
[示例 2:普通文件的创建与删除](#示例 2:普通文件的创建与删除)
[示例 3:目录的创建(mkdir 与 mkdirs 的区别)](#示例 3:目录的创建(mkdir 与 mkdirs 的区别))
[示例 4:文件重命名与移动](#示例 4:文件重命名与移动)
[3. 文件内容的读写:数据流体系](#3. 文件内容的读写:数据流体系)
[3.1 数据流的基本概念](#3.1 数据流的基本概念)
[3.2 字节输入流:InputStream 与 FileInputStream](#3.2 字节输入流:InputStream 与 FileInputStream)
[InputStream 核心方法](#InputStream 核心方法)
[3.3 字节输出流:OutputStream 与 FileOutputStream](#3.3 字节输出流:OutputStream 与 FileOutputStream)
[OutputStream 核心方法](#OutputStream 核心方法)
[3.4 字符流的便捷处理:Scanner 与 PrintWriter](#3.4 字符流的便捷处理:Scanner 与 PrintWriter)
[代码示例:使用 Scanner 读取文本文件](#代码示例:使用 Scanner 读取文本文件)
[代码示例:使用 PrintWriter 写入文本文件](#代码示例:使用 PrintWriter 写入文本文件)
[4. 实战小程序:文件操作综合应用](#4. 实战小程序:文件操作综合应用)
[4.1 扫描目录并删除指定文件](#4.1 扫描目录并删除指定文件)
[4.2 普通文件的复制](#4.2 普通文件的复制)
[4.3 扫描目录查找包含指定内容的文件](#4.3 扫描目录查找包含指定内容的文件)
[5. 常用代码参考模板](#5. 常用代码参考模板)
[5.1 按字节读取文件](#5.1 按字节读取文件)
[5.2 按字节写入文件](#5.2 按字节写入文件)
[5.3 按字符读取文件](#5.3 按字符读取文件)
[5.4 按字符写入文件](#5.4 按字符写入文件)
[6. 总结](#6. 总结)
1. 认识文件系统
在学习 Java 文件操作之前,我们首先需要理解操作系统层面的文件系统是如何组织和管理数据的。文件是计算机中持久化存储数据的基本单位,所有程序运行时产生的数据最终都需要通过文件系统保存到硬盘等持久化设备中。
1.1 文件的基本概念
狭义上的文件是指硬盘上独立存储的数据单元,就像办公桌上的一份份真实文件。每个文件包含两部分信息:
- 数据内容:文件中实际存储的用户数据
- 元信息:不属于文件内容本身的描述信息,如文件名、文件类型、文件大小、修改时间、权限等
1.2 树形结构与目录
随着文件数量的增加,需要一种高效的方式来组织和管理文件。现代操作系统普遍采用树形结构 来组织文件,这种结构中专门用来存放管理信息的特殊文件就是我们常说的文件夹 或目录。
- Windows 系统的树形结构示例:
此电脑 > C盘 > Program Files > Java - Linux 系统的树形结构示例:
/usr/bin/java
目录中保存的其实就是文件的元信息,通过层级化的目录结构,我们可以清晰地分类和查找文件。
1.3 文件路径与分隔符
文件路径是定位文件在树形结构中位置的唯一标识,分为两种:
- 绝对路径 :从根节点开始描述的完整路径,如 Windows 的
C:\Windows\System32\cmd.exe,Linux 的/usr/bin/java- 相对路径 :从当前所在节点出发描述的路径,其中
.代表当前目录,..代表父目录,如..\Windows NT
路径分隔符在不同操作系统中有所不同:
- Windows 使用反斜杠
\(Java 中需要转义为\\) Linux 和 MacOS 使用正斜杠/
Java 提供了File.pathSeparator常量来获取系统相关的路径分隔符,实现跨平台兼容。
1.4 文件类型与权限
根据保存数据的不同,文件可以分为:
- 文本文件:保存被字符集编码的文本数据,可以用文本编辑器直接打开查看
- 二进制文件:按照特定格式保存的非字符编码数据,如图片、视频、可执行程序等
Windows 系统通过文件名后缀来识别文件类型(如.exe是可执行程序,.dll是动态库),而 Linux 和 MacOS 系统则不依赖后缀名,而是通过文件内容来判断类型。操作系统还为文件提供了权限管理机制,一般包括可读 、可写 、可执行三种基本权限,通过权限系统可以保护数据安全。

1.5 "万物皆文件" 理念
为了实现接口的统一性,Unix 和 Linux 操作系统将所有的 I/O 设备都抽象成了文件的概念,包括硬盘、键盘、鼠标、网络套接字等。这种 "万物皆文件" 的设计思想极大地简化了程序对不同设备的操作方式。
2. Java 中操作文件:File 类详解
Java 通过java.io.File类来对文件和目录进行抽象描述。需要特别注意的是:有 File 对象并不代表真实存在该文件,File 对象只是对文件路径和元信息的抽象表示。
2.1 File 类概述
File 类主要用于处理文件的元信息和路径操作,不涉及文件内容的读写。它提供了一系列方法来创建、删除、重命名文件和目录,以及查询文件的属性信息。
2.2 File 类核心属性与构造方法
构造方法
| 签名 | 说明 |
|---|---|
| File(File parent, String child) | 根据父目录 File 对象 + 孩子文件路径创建 File 实例 |
| File(String pathname) | 根据文件路径创建 File 实例,路径可以是绝对路径或相对路径 |
| File(String parent, String child) | 根据父目录路径 + 孩子文件路径创建 File 实例 |
2.3 File 类常用方法
表格
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| String | getParent() | 返回 File 对象的父目录文件路径 |
| String | getName() | 返回 File 对象的纯文件名称 |
| String | getPath() | 返回 File 对象的文件路径 |
| String | getAbsolutePath() | 返回 File 对象的绝对路径 |
| String | getCanonicalPath() | 返回 File 对象的规范绝对路径(去除冗余的.和..) |
| boolean | exists() | 判断 File 对象描述的文件是否真实存在 |
| boolean | isDirectory() | 判断 File 对象代表的是否是一个目录 |
| boolean | isFile() | 判断 File 对象代表的是否是一个普通文件 |
| boolean | createNewFile() | 创建一个空文件,成功返回 true |
| boolean | delete() | 删除文件或空目录,成功返回 true |
| void | deleteOnExit() | 标注文件将在 JVM 运行结束时删除 |
| String\[\] | list() | 返回目录下的所有文件名数组 |
| File\[\] | listFiles() | 返回目录下的所有文件的 File 对象数组 |
| boolean | mkdir() | 创建单级目录,成功返回 true |
| boolean | mkdirs() | 创建多级目录(包括中间不存在的目录),成功返回 true |
| boolean | renameTo(File dest) | 重命名文件或移动文件,成功返回 true |
| boolean | canRead() | 判断用户是否对文件有可读权限 |
| boolean | canWrite() | 判断用户是否对文件有可写权限 |
2.4 代码示例:文件与目录的基本操作
示例 1:路径相关方法的差异
java
import java.io.File;
import java.io.IOException;
public class FilePathDemo {
public static void main(String[] args) throws IOException {
// 并不要求该文件真实存在
File file = new File("..\\hello-world.txt");
System.out.println("父目录: " + file.getParent());
System.out.println("文件名: " + file.getName());
System.out.println("构造路径: " + file.getPath());
System.out.println("绝对路径: " + file.getAbsolutePath());
System.out.println("规范路径: " + file.getCanonicalPath());
}
}
运行结果:
父目录: ..
文件名: hello-world.txt
构造路径: ..\hello-world.txt
绝对路径: D:\代码练习\文件示例1\..\hello-world.txt
规范路径: D:\代码练习\hello-world.txt
示例 2:普通文件的创建与删除
java
import java.io.File;
import java.io.IOException;
public class FileCreateDeleteDemo {
public static void main(String[] args) throws IOException {
File file = new File("hello-world.txt");
System.out.println("文件是否存在: " + file.exists());
System.out.println("是否是目录: " + file.isDirectory());
System.out.println("是否是普通文件: " + file.isFile());
// 创建新文件
System.out.println("创建文件是否成功: " + file.createNewFile());
System.out.println("文件是否存在: " + file.exists());
System.out.println("是否是目录: " + file.isDirectory());
System.out.println("是否是普通文件: " + file.isFile());
// 再次创建会失败,因为文件已存在
System.out.println("再次创建文件是否成功: " + file.createNewFile());
// 删除文件
System.out.println("删除文件是否成功: " + file.delete());
System.out.println("文件是否存在: " + file.exists());
}
}
运行结果:
文件是否存在: false
是否是目录: false
是否是普通文件: false
创建文件是否成功: true
文件是否存在: true
是否是目录: false
是否是普通文件: true
再次创建文件是否成功: false
删除文件是否成功: true
文件是否存在: false
示例 3:目录的创建(mkdir 与 mkdirs 的区别)
java
import java.io.File;
import java.io.IOException;
public class DirectoryCreateDemo {
public static void main(String[] args) throws IOException {
// 测试mkdir()方法:只能创建单级目录
File dir1 = new File("some-parent\\some-dir");
System.out.println("mkdir创建多级目录: " + dir1.mkdir()); // 失败,因为some-parent不存在
// 测试mkdirs()方法:可以创建多级目录
File dir2 = new File("some-parent\\some-dir");
System.out.println("mkdirs创建多级目录: " + dir2.mkdirs()); // 成功
System.out.println("是否是目录: " + dir2.isDirectory());
System.out.println("是否是普通文件: " + dir2.isFile());
}
}
运行结果:
mkdir创建多级目录: false
mkdirs创建多级目录: true
是否是目录: true
是否是普通文件: false
示例 4:文件重命名与移动
java
import java.io.File;
import java.io.IOException;
public class FileRenameDemo {
public static void main(String[] args) throws IOException {
// 先创建源文件
File source = new File("source.txt");
source.createNewFile();
File dest = new File("dest.txt");
System.out.println("源文件是否存在: " + source.exists());
System.out.println("目标文件是否存在: " + dest.exists());
// 重命名文件
System.out.println("重命名是否成功: " + source.renameTo(dest));
System.out.println("源文件是否存在: " + source.exists());
System.out.println("目标文件是否存在: " + dest.exists());
// 清理测试文件
dest.delete();
}
}
运行结果:
源文件是否存在: true
目标文件是否存在: false
重命名是否成功: true
源文件是否存在: false
目标文件是否存在: true
3. 文件内容的读写:数据流体系
File 类只能处理文件的元信息和路径操作,要读写文件内容,我们需要使用 Java 的数据流(Stream)体系。数据流是 Java 中处理 I/O 操作的核心抽象,它将数据的读写过程比作水流从一个地方流向另一个地方。
3.1 数据流的基本概念
- 输入流(InputStream):从数据源(如文件、键盘)读取数据到程序中,相当于 "接水"
- 输出流(OutputStream):将程序中的数据写入到目的地(如文件、屏幕),相当于 "灌水"
根据处理数据的单位不同,数据流又可以分为:
- 字节流:以字节为单位处理数据,可以处理所有类型的文件(文本、二进制)
- 字符流:以字符为单位处理数据,专门用于处理文本文件,会自动处理字符编码问题
3.2 字节输入流:InputStream 与 FileInputStream
InputStream是所有字节输入流的抽象父类,它定义了字节输入流的基本操作。我们主要使用它的子类FileInputStream来从文件中读取字节数据。
InputStream 核心方法
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| int | read() | 读取一个字节的数据,返回 - 1 表示已读完 |
| int | read(byte\[\] b) | 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量,-1 表示已读完 |
| int | read(byte\[\] b, int off, int len) | 最多读取 len 字节的数据到 b 中,从 off 位置开始存放,返回实际读到的数量,-1 表示已读完 |
| void | close() | 关闭字节流,释放资源 |
代码示例:文件读取的两种方式
java
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileReadDemo {
public static void main(String[] args) throws IOException {
// 方式1:单个字节读取(效率较低)
System.out.println("方式1:单个字节读取");
try (InputStream is = new FileInputStream("hello.txt")) {
while (true) {
int b = is.read();
if (b == -1) {
break;
}
System.out.printf("%c", (char) b);
}
}
System.out.println("\n\n方式2:缓冲区读取(效率较高)");
// 方式2:使用缓冲区读取(减少IO次数,性能更好)
try (InputStream is = new FileInputStream("hello.txt")) {
byte[] buf = new byte[1024];
int len;
while (true) {
len = is.read(buf);
if (len == -1) {
break;
}
for (int i = 0; i < len; i++) {
System.out.printf("%c", (char) buf[i]);
}
}
}
}
}
注意 :上述代码使用了 Java 7 引入的try-with-resources语法,它会自动关闭流资源,避免资源泄漏。
3.3 字节输出流:OutputStream 与 FileOutputStream
OutputStream是所有字节输出流的抽象父类,它定义了字节输出流的基本操作。我们主要使用它的子类FileOutputStream来向文件中写入字节数据。
OutputStream 核心方法
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| void | write(int b) | 写入一个字节的数据 |
| void | write(byte\[\] b) | 将 b 数组中的所有数据写入流中 |
| void | write(byte\[\] b, int off, int len) | 将 b 数组中从 off 开始的 len 个字节写入流中 |
| void | close() | 关闭字节流,释放资源 |
| void | flush() | 刷新缓冲区,将缓冲区中的数据强制写入设备 |
重要说明 :大多数 OutputStream 为了提高性能,会将数据先写入内存缓冲区,直到缓冲区满或关闭流时才真正写入设备。因此,在写入完成后必须调用flush()方法,确保所有数据都被写入文件。
代码示例:文件写入
java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileWriteDemo {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
// 写入单个字节
os.write('H');
os.write('e');
os.write('l');
os.write('l');
os.write('o');
// 写入字节数组
byte[] bytes = " World!".getBytes();
os.write(bytes);
// 写入字节数组的一部分
byte[] moreBytes = " This is a test.".getBytes();
os.write(moreBytes, 0, 10);
// 写入中文(指定UTF-8编码)
String chinese = " 你好中国";
byte[] chineseBytes = chinese.getBytes("UTF-8");
os.write(chineseBytes);
// 刷新缓冲区
os.flush();
}
System.out.println("文件写入完成");
}
}
3.4 字符流的便捷处理:Scanner 与 PrintWriter
直接使用字节流处理文本文件时,需要手动处理字符编码问题,比较麻烦。Java 提供了更便捷的字符流处理方式:
- 使用
Scanner读取文本文件 - 使用
OutputStreamWriter和PrintWriter写入文本文件
代码示例:使用 Scanner 读取文本文件
java
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class ScannerReadDemo {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("hello.txt")) {
// 指定UTF-8字符集读取
try (Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
}
}
}
}
代码示例:使用 PrintWriter 写入文本文件
java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class PrintWriterWriteDemo {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
// 指定UTF-8字符集写入
try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
try (PrintWriter writer = new PrintWriter(osWriter)) {
// 使用熟悉的print/println/printf方法
writer.println("我是第一行");
writer.print("我的第二行\r\n");
writer.printf("%d: 我的第三行\r\n", 1 + 1);
writer.println("你好中国");
// 刷新缓冲区
writer.flush();
}
}
}
System.out.println("文本写入完成");
}
}
4. 实战小程序:文件操作综合应用
掌握了文件的基本操作和内容读写后,我们来实现几个实用的小工具程序,巩固所学知识。
4.1 扫描目录并删除指定文件
功能:扫描指定目录,找到名称中包含指定字符的所有普通文件,并询问用户是否要删除该文件。
java
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class FileScannerAndDeleter {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入要扫描的根目录(绝对路径 OR 相对路径): ");
String rootDirPath = scanner.next();
File rootDir = new File(rootDirPath);
if (!rootDir.isDirectory()) {
System.out.println("您输入的根目录不存在或者不是目录,退出");
return;
}
System.out.print("请输入要找出的文件名中的字符: ");
String token = scanner.next();
List<File> result = new ArrayList<>();
// 使用深度优先遍历扫描目录
scanDir(rootDir, token, result);
System.out.println("共找到了符合条件的文件 " + result.size() + " 个");
for (File file : result) {
System.out.print(file.getCanonicalPath() + " 请问您是否要删除该文件(y/n): ");
String in = scanner.next();
if (in.toLowerCase().equals("y")) {
if (file.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
}
}
scanner.close();
}
private static void scanDir(File rootDir, String token, List<File> result) {
File[] files = rootDir.listFiles();
if (files == null || files.length == 0) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
// 递归扫描子目录
scanDir(file, token, result);
} else {
// 检查文件名是否包含指定字符
if (file.getName().contains(token)) {
result.add(file.getAbsoluteFile());
}
}
}
}
}
4.2 普通文件的复制
功能:将一个普通文件复制到指定的目标路径。
java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;
public class FileCopyTool {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入要复制的文件(绝对路径 OR 相对路径): ");
String sourcePath = scanner.next();
File sourceFile = new File(sourcePath);
if (!sourceFile.exists()) {
System.out.println("文件不存在,请确认路径是否正确");
return;
}
if (!sourceFile.isFile()) {
System.out.println("文件不是普通文件,请确认路径是否正确");
return;
}
System.out.print("请输入要复制到的目标路径(绝对路径 OR 相对路径): ");
String destPath = scanner.next();
File destFile = new File(destPath);
if (destFile.exists()) {
if (destFile.isDirectory()) {
System.out.println("目标路径已经存在,并且是一个目录,请确认路径是否正确");
return;
}
if (destFile.isFile()) {
System.out.print("目标文件已经存在,是否要进行覆盖? y/n: ");
String ans = scanner.next();
if (!ans.toLowerCase().equals("y")) {
System.out.println("停止复制");
return;
}
}
}
// 执行文件复制
try (InputStream is = new FileInputStream(sourceFile)) {
try (OutputStream os = new FileOutputStream(destFile)) {
byte[] buf = new byte[1024];
int len;
while (true) {
len = is.read(buf);
if (len == -1) {
break;
}
os.write(buf, 0, len);
}
os.flush();
}
}
System.out.println("复制已完成");
scanner.close();
}
}
4.3 扫描目录查找包含指定内容的文件
功能:扫描指定目录,找到名称或内容中包含指定字符的所有普通文件。
java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ContentFileSearcher {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入要扫描的根目录(绝对路径 OR 相对路径): ");
String rootDirPath = scanner.next();
File rootDir = new File(rootDirPath);
if (!rootDir.isDirectory()) {
System.out.println("您输入的根目录不存在或者不是目录,退出");
return;
}
System.out.print("请输入要查找的字符: ");
String token = scanner.next();
List<File> result = new ArrayList<>();
// 使用深度优先遍历扫描目录
scanDirWithContent(rootDir, token, result);
System.out.println("共找到了符合条件的文件 " + result.size() + " 个,它们分别是:");
for (File file : result) {
System.out.println(file.getCanonicalPath());
}
scanner.close();
}
private static void scanDirWithContent(File rootDir, String token, List<File> result) {
File[] files = rootDir.listFiles();
if (files == null || files.length == 0) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
// 递归扫描子目录
scanDirWithContent(file, token, result);
} else {
// 检查文件名或内容是否包含指定字符
if (file.getName().contains(token) || isContentContains(file, token)) {
result.add(file.getAbsoluteFile());
}
}
}
}
// 检查文件内容是否包含指定字符(按UTF-8编码处理)
private static boolean isContentContains(File file, String token) throws IOException {
StringBuilder sb = new StringBuilder();
try (InputStream is = new FileInputStream(file)) {
try (Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNextLine()) {
sb.append(scanner.nextLine());
sb.append("\r\n");
}
}
}
return sb.indexOf(token) != -1;
}
}
注意:该方案性能较差,尽量不要在太复杂的目录下或者大文件下使用。
5. 常用代码参考模板
为了方便大家在实际开发中快速使用,这里整理了文件操作中最常用的代码模板。
5.1 按字节读取文件
java
try (InputStream is = new FileInputStream("文件路径")) {
byte[] buf = new byte[1024];
while (true) {
int n = is.read(buf);
if (n == -1) {
break;
}
// buf 的 [0, n) 表示读到的数据,按业务进行处理
}
}
5.2 按字节写入文件
java
try (OutputStream os = new FileOutputStream("文件路径")) {
byte[] buf = new byte[1024];
while (/* 还有未完成的业务数据 */) {
// 将业务数据填入 buf 中,长度为 n
int n = /* 实际数据长度 */;
os.write(buf, 0, n);
}
os.flush(); // 进行数据刷新操作
}
5.3 按字符读取文件
java
try (InputStream is = new FileInputStream("文件路径")) {
try (Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// 根据 line 做业务处理
}
}
}
5.4 按字符写入文件
java
try (OutputStream os = new FileOutputStream("文件路径")) {
try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
try (PrintWriter writer = new PrintWriter(osWriter)) {
while (/* 还有未完成的业务数据 */) {
writer.println(/* 要写入的内容 */);
}
writer.flush(); // 进行数据刷新操作
}
}
}
6. 总结
本文从文件系统基础讲起,详细介绍了 Java 中文件操作和 IO 流的核心知识:
- 文件系统基础:理解文件的概念、树形结构、路径表示、文件类型和权限,以及 "万物皆文件" 的设计思想。
- File 类:掌握 File 类的核心方法,能够进行文件和目录的创建、删除、重命名、属性查询等操作。
- 数据流体系:理解字节流和字符流的区别,掌握 InputStream 和 OutputStream 的基本使用,以及 Scanner 和 PrintWriter 的便捷用法。
- 资源管理:使用 try-with-resources 语法自动关闭流资源,避免资源泄漏。
- 实战应用:通过三个实用的小程序,掌握文件操作的综合应用。
文件操作和 IO 流是 Java 编程的基础,几乎所有的应用程序都需要与文件系统进行交互。掌握这些知识,能够帮助我们编写更加健壮和高效的 Java 程序。欢迎大家的指导,在后续的学习中,小编这里会继续努力加油