一,文件管理最核心、最有效的组织思想
1)树形结构

2)目录

注意
路径分隔符
Windows:使用反斜杠
macOS / Linux:使用正斜杠
二,文件路径
- 绝对路径
定义:从文件系统的根目录开始,完整地指定文件位置的路径
特点:具有唯一性。无论你的当前目录在哪里,同一个文件的绝对路径始终是相同的
作用:用于精确、无歧义地定位一个文件 - 相对路径
定义:以当前工作目录为起点,来描述目标文件位置的路径
特点:它依赖于你当前的位置。在不同的目录下,指向同一个文件的相对路径是不同的
作用:更加简洁、灵活,特别适用于项目内部的文件引用

三,文件分类
1)文本文件
文本文件是一种其内容完全由字符构成的文件。这些字符来自一个特定的字符集(如英文字母、数字、标点符号、换行符等)。计算机将这些字符按照某种字符编码规则(ASCII,UTF-8等)转换成数字存储起来
2)二进制文件
二进制文件存储的不是"字符",而是原始的字节序列。这些字节可以代表任何东西:像素颜色、机器指令、音频样本、压缩数据等。它没有"字符编码"的概念,其格式完全由创建它的应用程序定义
四,File类
File类位于 java.io 包中,用于文件和目录的创建、删除、重命名等操作,可以获取文件属性信息
1)File类常见的构造方法
java
// 1. 通过路径字符串创建
File(String pathname)
// 这种情况为相对路径 - 相对于当前工作目录
File file1 = new File("data.txt");
// 2. 通过父路径和子路径创建
File(String parent, String child)
// 这种情况将在父路径下创建一个字路径
File file2 = new File("C:/Users/john", "documents/report.pdf");
// 3. 通过父File对象和子路径创建
File(File parent, String child)
File parentDir = new File("C:/workspace");
// 创建子文件
File sourceFile = new File(parentDir, "src/Main.java");
2)File类与路径相关的常见方法

java
File file = new File("testDir/../src/Main.java");
System.out.println("Path: " + file.getPath());
// 输出: Path: testDir/../src/Main.java
System.out.println("Absolute Path: " + file.getAbsolutePath());
// 输出: Absolute Path: /workspace/testDir/../src/Main.java
System.out.println("Canonical Path: " + file.getCanonicalPath());
// 输出: Canonical Path: /workspace/src/Main.java
System.out.println("Name: " + file.getName());
// 输出: Name: Main.java
System.out.println("Parent: " + file.getParent());
// 输出: Parent: testDir/../src

java
File file = new File("/home/user/documents");
System.out.println("Is Absolute: " + file.isAbsolute()); // true
System.out.println("Exists: " + file.exists()); // 检查是否存在
System.out.println("Is Directory: " + file.isDirectory()); // 是否为目录
3)File类操作文件或目录
- 创建文件(createNewFile())
特点:
返回boolean类型值
只能创建文件,不能创建目录
如果文件已存在,返回 false
需要处理 IOException
java
File file = new File("newFile.txt");
try {
if (file.createNewFile()) {
System.out.println("文件创建成功!");
} else {
System.out.println("文件已存在或创建失败");
}
} catch (IOException e) {
e.printStackTrace();
}
- 删除文件 与 空目录(delete())
特点:
返回boolean类型值
可以删除文件或空目录
删除后无法恢复
如果文件被占用,删除可能失败
java
File file = new File("fileToDelete.txt");
if (file.delete()) {
System.out.println("文件删除成功!");
} else {
System.out.println("文件删除失败(文件不存在或正在被使用)");
}
File emptyDir = new File("emptyDirectory");
if (emptyDir.delete()) {
System.out.println("空目录删除成功!");
} else {
System.out.println("目录删除失败(目录不为空或不存在)");
}
- 创建目录(mkdirs()和mkdir())
mkdirs() 方法会创建此 File 对象所表示的目录,包括所有必需但不存在的父目录,它会递归地创建整个目录路径
mkdir() 方法尝试创建此 File 对象所表示的目录
java
File dir = new File("newDirectory");
if (dir.mkdir()) {
System.out.println("目录创建成功!");
} else {
System.out.println("目录创建失败(可能父目录不存在)");
}
File multiDir = new File("parent/child/grandchild");
if (multiDir.mkdirs()) {
System.out.println("多级目录创建成功!");
} else {
System.out.println("多级目录创建失败");
}
- 目录遍历方法list()和listFiles()

java
File directory = new File("C:/test");
// 获取目录中的所有文件和目录的File对象
File[] files = directory.listFiles();
if (files != null) {
System.out.println("目录详细信息:");
for (File file : files) {
System.out.println("名称: " + file.getName());
System.out.println("路径: " + file.getAbsolutePath());
System.out.println("类型: " + (file.isFile() ? "文件" : "目录"));
System.out.println("大小: " + file.length() + " bytes");
System.out.println("可读: " + file.canRead());
System.out.println("可写: " + file.canWrite());
System.out.println("最后修改: " + new Date(file.lastModified()));
System.out.println("---");
}
} else {
System.out.println("指定的路径不是目录或无法访问");
}

4)deleteOnExit()
deleteOnExit() 是 File 类中的一个方法,它在 JVM 虚拟机正常退出时删除此抽象路径名表示的文件或目录
特点:
延迟删除:不是立即删除,而是注册一个删除钩子
JVM 退出时执行:只有在虚拟机正常终止时才会执行删除
不可取消:一旦注册,无法取消删除操作
适用于临时文件:主要用于程序运行期间创建的临时文件清理
5)renameTo()
renameTo()是Java File类中的一个方法,用于重命名或移动文件/目录
- 重命名功能
java
import java.io.File;
public class RenameExample {
public static void main(String[] args) {
File oldFile = new File("oldname.txt");
File newFile = new File("newname.txt");
if (oldFile.renameTo(newFile)) {
System.out.println("文件重命名成功");
} else {
System.out.println("文件重命名失败");
}
}
}
- 移动功能
java
import java.io.File;
public class MoveFileExample {
public static void main(String[] args) {
File sourceFile = new File("source.txt");
File destFile = new File("new_directory/source.txt");
// 确保目标目录存在
new File("new_directory").mkdirs();
if (sourceFile.renameTo(destFile)) {
System.out.println("文件移动成功");
} else {
System.out.println("文件移动失败");
}
}
}
五,流
计算机科学中,"流"就是一个抽象概念:
- 核心思想: 它代表了一个连续、有序的数据序列,可以从源端连续地传输到目的端
- 关键优势: 无需一次性将所有数据加载到内存中。这对于处理大型文件(如几个GB的视频文件)至关重要,因为内存可能根本无法容纳整个文件。流允许你像"拧开水龙头"一样,一小块一小块地处理数据。
- 抽象性: "流"隐藏了底层数据源和数据目的地的具体细节。无论是来自硬盘上的文件、网络连接、内存块,还是键盘输入,在程序眼中,它们都可以被统一看作是"流"
流的分类:


六,字节输入流InputStream
InputStream 是所有字节输入流的基类,它是一个抽象类,定义了字节输入流的基本操作方法,对于文件来说FileInputStream是实现该抽象类的字节输入流
1)InputStream中的重要方法

注意:
- InputStream中的方法都声明了throws IOException需要对异常进行处理
- read()返回值看似是int实则是byte,取值为0-255
原因:计算机读取文件时,实际读到的数据是无符号8位整数(0-255),但Java的byte类型是有符号的(-128到127)。为了避免混淆和方便表示EOF,API设计者选择用int来包装这个无符号字节值
java
// 如果只返回byte(0-255),没有额外的值表示"结束"
int result = inputStream.read();
if (result == -1) {
// 文件结束
// 如果byte是无符号0-255,就没有-1这个值了
}

- 除无参数read方法以外,另外两个方法返回值都是读取到的实际长度
- 一般使用read()较少,由于一次仅读一个字节效率较低
2)FileInputStream的构造方法
FileInputStream的构造方法的参数就是要确定需要读入程序的文件
java
// 通过文件路径创建
FileInputStream(String name)
// 通过File对象创建
FileInputStream(File file)
在具体使用时一定要记得关闭资源因此需要搭配try使用
有两种使用方案
- 将InputStream定义在try外部
java
InputStream is = null;
try {
//如果定义在内部,由于Java 的变量作用域规则执行final语句时is已经离开了作用域
// InputStream is = new FileInputStream("test.txt");
is = new FileInputStream("test.txt");
// 使用流
} finally {
is.close();
}
- 使用try-with-resources(推荐使用)
try-with-resources用于自动资源管理,它确保在语句结束时自动关闭所有实现了 AutoCloseable 或 Closeable 接口的资源,简单来说就是会自动关闭资源
java
//能放入括号里的都是实现了 AutoCloseable或Closeable接口的
try (InputStream is = new FileInputStream("test.txt")) {
// 使用流...
// 自动关闭,无需 finally
}
注意,不关闭资源将会造成资源泄露,可能造成严重后果
七,字节输出流OnputStream
Java中的字节输出流 OutputStream 是所有输出字节流的抽象基类。它定义了写入字节数据的基本方法。具体实现类如FileOutputStream
1)核心方法write

2)FileOutputStream的构造方法
java
// 覆盖模式写入
FileOutputStream fos1 = new FileOutputStream("output.txt");
// 追加模式写入
FileOutputStream fos2 = new FileOutputStream("output.txt", true);
// 使用File对象
File file = new File("output.txt");
FileOutputStream fos3 = new FileOutputStream(file);
//使用File对象的追加模式写入
File file = new File("output.txt");
FileOutputStream fos3 = new FileOutputStream(file,true);
重点在于追加模式
打开OutputStream对象时默认会清空文件原有内容,因此在需要保存原内容时,应采用追加模式
八,字符输入流Reader
Reader 是 Java 中用于读取字符流的抽象基类,与 InputStream(字节流)相对应
1)read方法
与InputStream相似
java
// 1. 读取单个字符无参数read
public int read() throws IOException {
char[] cb = new char[1];
if (read(cb, 0, 1) == -1) return -1;
else return cb[0];
}
// 2. 读取到字符数组
public int read(char[] cbuf) throws IOException {
return read(cbuf, 0, cbuf.length);
}
// 3. 读取到字符数组的一部分
public abstract int read(char[] cbuf, int off, int len) throws IOException;
注意:由于读取的是字符可能需考虑编码问题
2)FileReader构造方法
java
// 1. 通过文件路径
FileReader(String fileName)
// 2. 通过File对象
FileReader(File file)
注意,字符输入流同样需要关闭资源,使用方法同InputStream
九,字符输出流Writer
Writer 是 Java 中用于写入字符流的抽象基类,与 OutputStream(字节流)相对应,但处理的是字符数据。
1)核心方法write
java
// 写入单个字符
public void write(int c) throws IOException
// 写入字符数组
public void write(char cbuf[]) throws IOException
// 写入字符数组的一部分
abstract public void write(char cbuf[], int off, int len) throws IOException
// 写入字符串
public void write(String str) throws IOException
// 写入字符串的一部分
public void write(String str, int off, int len) throws IOException
2)FileWriter的构造方法
java
// 1. 通过文件路径
FileWriter(String fileName) throws IOException
// 2. 追加模式
FileWriter(String fileName, boolean append) throws IOException
// 3. 通过File对象
FileWriter(File file) throws IOException
// 4. 追加模式 + File对象
FileWriter(File file, boolean append) throws IOException
与Outputstream基本同理
十,在scanner中的System.in
System.in本质上也是个InputStream,因此Scanner的参数也可以是InputStream
java
Scanner scanner = new Scanner(inputstream);
while (scanner.hasNext()) {
String s = scanner.next();
System.out.println(s);
}
特别注意!
虽然仅强调了输入流的资源关闭,实际过程中无论输入流输出流,都尽可能的去关闭资源