文件流
java.io.File
类是专门对文件进行操作的类,注意只能对文件本身进行操作,不能对文件内容进行操作,想要操作内容,必须借助输入输出流。
File
类是文件和目录的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
File 构造方法
比较常用的构造方法有三个:
1、 File(String pathname)
:通过给定的路径来创建新的 File 实例。
2、 File(String parent, String child)
:从父路径(字符串)和子路径创建新的 File 实例。
3、 File(File parent, String child)
:从父路径(File)和子路径创建新的 File 实例。
// 文件路径名
String path = "/Users/username/123.txt";
File file1 = new File(path);
// 文件路径名
String path2 = "/Users/username/1/2.txt";
File file2 = new File(path2); -------------相当于/Users/username/1/2.txt
// 通过父路径和子路径字符串
String parent = "/Users/username/aaa";
String child = "bbb.txt";
File file3 = new File(parent, child); --------相当于/Users/username/aaa/bbb.txt
// 通过父级File对象和子路径字符串
File parentDir = new File("/Users/username/aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child); --------相当于/Users/username/aaa/bbb.txt
注意,macOS 路径使用正斜杠(/
)作为路径分隔符,而 Windows 路径使用反斜杠(\
)作为路径分隔符。所以在遇到路径分隔符的时候,不要直接去写/
或者\
。
Java 中提供了一个跨平台的方法来获取路径分隔符,即使用 File.separator
,这个属性会根据操作系统自动返回正确的路径分隔符。
File 类的注意点:
- 一个 File 对象代表硬盘中实际存在的一个文件或者目录。
- File 类的构造方法不会检验这个文件或目录是否真实存在,因此无论该路径下是否存在文件或者目录,都不影响 File 对象的创建。
File 常用方法
获取功能
-
getAbsolutePath()
:返回此 File 的绝对路径。 -
getPath()
:结果和 getAbsolutePath 一致。 -
getName()
:返回文件名或目录名。 -
length()
:返回文件长度,以字节为单位。
判断功能
-
exists()
:判断文件或目录是否存在。 -
isDirectory()
:判断是否为目录。 -
isFile()
:判断是否为文件。
创建删除
createNewFile()
:文件不存在,创建一个新的空文件并返回true
,文件存在,不创建文件并返回false
。delete()
:删除文件或目录。如果是目录,只有目录为空才能删除。mkdir()
:只能创建一级目录,如果父目录不存在,则创建失败。返回 true 表示创建成功,返回 false 表示创建失败。mkdirs()
:可以创建多级目录,如果父目录不存在,则会一并创建。返回 true 表示创建成功,返回 false 表示创建失败或目录已经存在。
开发中一般用mkdirs()
;
目录的遍历
String[] list()
:返回一个 String 数组,表示该 File 目录中的所有子文件或目录。File[] listFiles()
:返回一个 File 数组,表示该 File 目录中的所有的子文件或目录。
listFiles在获取指定目录下的文件或者子目录时必须满足下面两个条件:
-
- 指定的目录必须存在
-
- 指定的必须是目录。否则容易引发 NullPointerException 异常
递归遍历
public static void traverseDirectory(File directory) {
// 列出目录下的所有文件和子目录
File[] filesAndDirs = directory.listFiles();
// 遍历每个文件和子目录
for (File fileOrDir : filesAndDirs) {
if (fileOrDir.isFile()) {
// 如果是文件,输出文件名
System.out.println("文件:" + fileOrDir.getName());
} else if (fileOrDir.isDirectory()) {
// 如果是目录,递归遍历子目录
System.out.println("目录:" + fileOrDir.getName());
traverseDirectory(fileOrDir);
}
}
}
RandomAccessFile
RandomAccessFile 是 Java 中一个非常特殊的类,它既可以用来读取文件,也可以用来写入文件。与其他 IO 类(如 FileInputStream 和 FileOutputStream)不同,RandomAccessFile 允许您跳转到文件的任何位置,从那里开始读取或写入。这使得它特别适用于需要在文件中随机访问数据的场景,如数据库系统。
public static void main(String[] args) {
String filePath = "hello.txt";
try {
// 使用 RandomAccessFile 写入文件
writeToFile(filePath, "Hello, World!");
// 使用 RandomAccessFile 读取文件
String content = readFromFile(filePath);
System.out.println("文件内容: " + content);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void writeToFile(String filePath, String content) throws IOException {
try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "rw")) {
// 将文件指针移动到文件末尾(在此处追加内容)
randomAccessFile.seek(randomAccessFile.length());
// 写入内容
randomAccessFile.writeUTF(content);
}
}
private static String readFromFile(String filePath) throws IOException {
StringBuilder content = new StringBuilder();
try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r")) {
// 将文件指针移动到文件开始处(从头开始读取)
randomAccessFile.seek(0);
content.append(randomAccessFile.readUTF());
}
return content.toString();
}
构造方法
RandomAccessFile 主要有两个构造方法:
RandomAccessFile(File file, String mode)
:使用给定的文件对象和访问模式创建一个新的 RandomAccessFile 实例。RandomAccessFile(String name, String mode)
:使用给定的文件名和访问模式创建一个新的 RandomAccessFile 实例。
访问模式 mode 的值可以是:
- "r":以只读模式打开文件。调用结果对象的任何 write 方法都将导致 IOException。
- "rw":以读写模式打开文件。如果文件不存在,它将被创建。
- "rws":以读写模式打开文件,并要求对内容或元数据的每个更新都被立即写入到底层存储设备。这种模式是同步的,可以确保在系统崩溃时不会丢失数据。
- "rwd":与“rws”类似,以读写模式打开文件,但仅要求对文件内容的更新被立即写入。元数据可能会被延迟写入。
主要方法
long getFilePointer()
:返回文件指针的当前位置。long length()
:返回此文件的长度。int read()
:从该文件中读取一个字节数据。int read(byte[] b)
:从该文件中读取字节数据并将其存储到指定的字节数组中。int read(byte[] b, int off, int len)
:从该文件中读取字节数据并将其存储到指定的字节数组中,从偏移量 off 开始,最多读取 len 个字节。String readLine()
:从该文件中读取一行文本。readUTF()
:从文件读取 UTF-8 编码的字符串。此方法首先读取两个字节的长度信息,然后根据这个长度读取字符串的 UTF-8 字节。最后,这些字节被转换为 Java 字符串。这意味着当你使用 readUTF 方法读取字符串时,需要确保文件中的字符串是使用 writeUTF 方法写入的,这样它们之间的长度信息和编码方式才能保持一致。void seek(long pos)
:将文件指针设置到文件中的 pos 位置。void write(byte[] b)
:将指定的字节数组的所有字节写入该文件。void write(byte[] b, int off, int len)
:将指定字节数组的部分字节写入该文件,从偏移量 off 开始,写入 len 个字节。void write(int b)
:将指定的字节写入该文件。writeUTF(String str)
:将一个字符串以 UTF-8 编码写入文件。此方法首先写入两个字节的长度信息,表示字符串的 UTF-8 字节长度,然后写入 UTF-8 字节本身。因此,当你使用 writeUTF 写入字符串时,实际写入的字节数会比字符串的 UTF-8 字节长度多两个字节。这两个字节用于在读取字符串时确定正确的字符串长度。
Apache FileUtils 类
FileUtils 类是 Apache Commons IO 库中的一个类,提供了一些更为方便的方法来操作文件或目录。
复制文件或目录
File srcFile = new File("path/to/src/file");
File destFile = new File("path/to/dest/file");
// 复制文件
FileUtils.copyFile(srcFile, destFile);
// 复制目录
FileUtils.copyDirectory(srcFile, destFile);
删除文件或目录
File file = new File("path/to/file");
// 删除文件或目录
FileUtils.delete(file);
需要注意的是,如果要删除一个非空目录,需要先删除目录中的所有文件和子目录。
移动文件或目录
File srcFile = new File("path/to/src/file");
File destFile = new File("path/to/dest/file");
// 移动文件或目录
FileUtils.moveFile(srcFile, destFile);
查询文件或目录的信息
File file = new File("path/to/file");
// 获取文件或目录的修改时间
Date modifyTime = FileUtils.lastModified(file);
// 获取文件或目录的大小
long size = FileUtils.sizeOf(file);
// 获取文件或目录的扩展名
String extension = FileUtils.getExtension(file.getName());
Hutool FileUtil 类
FileUtil 类是 Hutool 工具包中的文件操作工具类,提供了一系列简单易用的文件操作方法,可以帮助 Java 开发者快速完成文件相关的操作任务。
FileUtil 类包含以下几类操作工具:
- 文件操作:包括文件目录的新建、删除、复制、移动、改名等
- 文件判断:判断文件或目录是否非空,是否为目录,是否为文件等等。
- 绝对路径:针对 ClassPath 中的文件转换为绝对路径文件。
- 文件名:主文件名,扩展名的获取
- 读操作:包括 getReader、readXXX 操作
- 写操作:包括 getWriter、writeXXX 操作
下面是 FileUtil 类中一些常用的方法:
1、copyFile:复制文件。该方法可以将指定的源文件复制到指定的目标文件中。
File dest = FileUtil.file("FileUtilDemo2.java");
FileUtil.copyFile(file, dest);
2、move:移动文件或目录。该方法可以将指定的源文件或目录移动到指定的目标文件或目录中。
FileUtil.move(file, dest, true);
3、del:删除文件或目录。该方法可以删除指定的文件或目录,如果指定的文件或目录不存在,则会抛出异常。
FileUtil.del(file);
4、rename:重命名文件或目录。该方法可以将指定的文件或目录重命名为指定的新名称。
FileUtil.rename(file, "FileUtilDemo3.java", true);
5、readLines:从文件中读取每一行数据。
FileUtil.readLines(file, "UTF-8").forEach(System.out::println);