IO流
File 类
File类位于java.io包中,主要用于表示文件和目录路径。- 注意:
File对象仅仅是路径名的抽象表示,并不一定对应一个真实存在的文件或目录。- 可以通过
File类完成对文件/目录的创建、删除、获取属性等操作,但读写文件内容还需要使用 IO 流。- 常见构造方法:
构造方法 说明 public File(String pathname)根据给定路径名字符串创建一个 File对象public File(String parent, String child)根据父路径和子路径字符串创建一个 File对象public File(File parent, String child)根据父 File对象和子路径字符串创建一个File对象Noteimport java.io.File; public class Main { public static void main(String[] args) { // 根据路径字符串创建 File 对象 File file1 = new File("test.txt"); // 根据父路径和子路径创建 File file2 = new File("/Users/sun", "test.txt"); // 根据父 File 对象和子路径创建 File parent = new File("/Users/sun"); File file3 = new File(parent, "test.txt"); // 打印对象信息 printFileInfo("file1", file1); printFileInfo("file2", file2); printFileInfo("file3", file3); } private static void printFileInfo(String name, File file) { System.out.println("==== " + name + " ===="); System.out.println("路径: " + file.getPath()); System.out.println("绝对路径: " + file.getAbsolutePath()); System.out.println("是否存在: " + file.exists()); System.out.println("是否是目录: " + file.isDirectory()); System.out.println("是否是文件: " + file.isFile()); System.out.println(); } }
常用方法
方法签名 说明 public String getName()只返回文件或目录的名称,不包含路径。 public String getPath()返回创建 File 对象时传入的路径字符串,不一定是绝对路径。 public String getAbsolutePath()返回绝对路径(会根据当前工作目录补全)。即使文件不存在,也能返回字符串。 public String getParent()返回父路径字符串(可能是相对路径)。若没有父路径则返回 null。public long length()返回文件大小(单位:字节)。目录调用此方法,返回值未指定(通常为 0)。不存在的文件也返回0。public long lastModified()返回文件最后修改时间(毫秒)。不存在的文件返回 0。public boolean exists()判断文件或目录是否真实存在。常用前置检查,很多方法调用前最好先判断。 public boolean isFile()判断是否是文件。存在且是文件时返回 true,不存在或目录时返回false。public boolean isDirectory()判断是否是目录。存在且是目录时返回 true,不存在时返回false。public boolean canRead()判断文件是否可读。结果受系统权限控制。 public boolean canWrite()判断文件是否可写。在只读目录或权限不足时会返回 false。public boolean isHidden()判断文件是否隐藏。不存在的文件返回 false。不同操作系统定义不同(Windows 取决于隐藏属性,Linux/macOS 以.开头)。public boolean createNewFile()创建一个新文件。文件已存在时返回 false。不能自动创建父目录,父目录不存在会抛IOException。public boolean delete()删除文件或空目录。非空目录删除失败。删除失败时返回 false,不会抛异常。public boolean mkdir()创建单级目录。父目录不存在时创建失败,返回 false。public boolean mkdirs()创建多级目录。父目录不存在时也会自动创建。 public String[] list()返回目录下所有文件/子目录的名称数组。只能对目录调用,否则返回 null。目录为空时返回空数组[]。public File[] listFiles()返回目录下所有文件/子目录的 File对象数组。只能对目录调用,否则返回null。空目录时返回空数组。
Note
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws IOException {
// 准备测试路径
File file = new File("test.txt");
File dir = new File("testDir");
File dirs = new File("a/b/c");
// 1. 创建文件
if (!file.exists()) {
file.createNewFile();
System.out.println("文件 test.txt 创建成功");
}
// 2. 获取文件信息
System.out.println("getName(): " + file.getName());
System.out.println("getPath(): " + file.getPath());
System.out.println("getAbsolutePath(): " + file.getAbsolutePath());
System.out.println("getParent(): " + file.getParent());
System.out.println("length(): " + file.length() + " 字节");
System.out.println("lastModified(): " +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date(file.lastModified())));
// 3. 判断方法
System.out.println("exists(): " + file.exists());
System.out.println("isFile(): " + file.isFile());
System.out.println("isDirectory(): " + file.isDirectory());
System.out.println("canRead(): " + file.canRead());
System.out.println("canWrite(): " + file.canWrite());
System.out.println("isHidden(): " + file.isHidden());
// 4. 创建目录
if (!dir.exists()) {
dir.mkdir();
System.out.println("目录 testDir 创建成功");
}
if (!dirs.exists()) {
dirs.mkdirs();
System.out.println("多级目录 a/b/c 创建成功");
}
// 5. 列出目录内容
File currentDir = new File(".");
String[] names = currentDir.list();
System.out.println("当前目录下的文件/目录名称:");
if (names != null) {
for (String name : names) {
System.out.println(" " + name);
}
}
File[] files = currentDir.listFiles();
System.out.println("当前目录下的文件/目录对象:");
if (files != null) {
for (File f : files) {
System.out.println(" " + f.getAbsolutePath());
}
}
// 6. 删除文件和目录(注意:delete() 不能删除非空目录)
if (file.delete()) {
System.out.println("文件 test.txt 删除成功");
}
if (dir.delete()) {
System.out.println("目录 testDir 删除成功");
}
if (dirs.delete()) {
System.out.println("目录 a/b/c 删除成功(如果是空目录)");
}
}
}
File 过滤器
在 Java 中,
File类提供了过滤器功能,用于筛选目录下的文件或文件夹。通过过滤器,我们可以控制listFiles()或list()方法返回的文件集合。
listFiles()可以接受两种类型的过滤器:
- FileFilter:接受一个
File对象作为参数,返回boolean,决定是否包含该文件或目录。- FilenameFilter:接受两个参数,第一个是当前目录的
File对象,第二个是文件名(字符串),返回boolean,决定是否包含该文件或目录。过滤器的使用:
方法 描述 File[] listFiles(FileFilter filter)使用 FileFilter过滤文件或目录File[] listFiles(FilenameFilter filter)使用 FilenameFilter过滤文件或目录String[] list(FilenameFilter filter)返回符合 FilenameFilter条件的文件名数组import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; public class Main { public static void main(String[] args) { File dir = new File("/"); // 使用 FileFilter 过滤器:只显示目录 File[] directories = dir.listFiles(new FileFilter() { @Override public boolean accept(File file) { return file.isDirectory(); } }); System.out.println("所有目录:"); for (File f : directories) { System.out.println(f.getName()); } // 使用 FilenameFilter 过滤器:只显示 .txt 文件 File[] txtFiles = dir.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".txt"); } }); System.out.println("所有 .txt 文件:"); for (File f : txtFiles) { System.out.println(f.getName()); } // 使用 Lambda 表达式简化 File[] javaFiles = dir.listFiles(f -> f.getName().endsWith(".java")); System.out.println("所有 .java 文件:"); for (File f : javaFiles) { System.out.println(f.getName()); } } }
IO 流概述
- 输入(Input):指程序从外部系统获取数据。核心含义是“读”,例如从文件、网络、数据库或内存中读取数据。
- 输出(Output):指程序将数据输出到外部系统。核心含义是“写”,例如将数据写入文件、网络连接或控制台。
- 数据源(Data Source):提供数据的媒介,可以是文件、数据库、内存、网络、外部设备等。
- 流的概念:流是一种有序的数据传输通道,程序通过流可以连续地读取或写入数据。
- 流的特点:
- 单向性:数据在流中只能单向传输,输入流从外部到程序,输出流从程序到外部。
- 有序性:数据按顺序读写,不能跳跃访问(除非使用随机访问类如 RandomAccessFile)。
- 连接性:流通常连接一个具体的数据源或目的地,通过流对象操作数据源。
- 常见场景:
- 从磁盘文件读取文本内容(InputStream/FileReader)
- 将程序输出写入日志文件(OutputStream/FileWriter)
- 网络通信(Socket InputStream/OutputStream)
- 数据库读写(通过流读取 Blob、Clob 等二进制或字符数据)
IO 流的分类
- 按流的方向:
- 输入流(Input Stream):数据从外部流向程序,典型类:
InputStream、Reader。
- 示例:
FileInputStream fis = new FileInputStream("data.txt");- 输出流(Output Stream):数据从程序流向外部,典型类:
OutputStream、Writer。
- 示例:
FileOutputStream fos = new FileOutputStream("data.txt");
按处理的数据单元:
字节流(Byte Stream):以字节为单位读写数据。适用于所有类型文件,包括文本、图片、音视频。 典型类:
InputStream、OutputStream及其子类。字符流(Character Stream):以字符为单位读写数据。专门用于文本文件,自动处理字符编码。 典型类:
Reader、Writer及其子类。
按处理对象不同:
节点流(Node Stream / 低级流):直接连接到数据源或目的地。 例如:
FileInputStream、FileOutputStream。处理流(Filter / 包装流):不直接连接数据源,而是包装其他流提供增强功能,例如缓冲、加密、压缩、对象序列化。 例如:
BufferedReader、BufferedOutputStream、DataInputStream。
