Java 文件操作

在平时编写程序的时候,经常会对文件进行操作,比如文件的赋值,重命名,删除等。接下来学习使用 Java 操作文件。

拷贝

可以使用 Files 工具类的 copy(Path source,Path target,CopyOption… options) 拷贝文件或者目录。如果目标文件存在,那么赋值将失败,除非我们在 options 中指定了 REPLACE_EXISTING 属性。当该命令复制目录时,如果目录中已经有了文件,目录中的文件将不会被复制。CopyOption 参数支持以下 StandardCopyOption 和 LinkOption 枚举:

  • REPLACE_EXISTING:即使目标文件已存在,也执行复制。如果目标是符号链接,则复制链接本身(而不是链接的目标)。如果目标是非空目录,则复制将失败并显示 FileAlreadyExistsException 异常。
  • COPY_ATTRIBUTES:将与文件关联的文件属性复制到目标文件。支持的确切 - 文件属性是文件系统和平台相关的,但 last-modified-time 跨平台支持并复制到目标文件。 NOFOLLOW_LINKS:表示不应遵循符号链接。如果要复制的文件是符号链接,则复制链接(而不是链接的目标)。

编程实例

新建文件 1.txt。 在 项目目录下新建源代码文件 CopyDemo.java。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class CopyDemo {
public static void main(String[] args) {
try {
//被拷贝的文件一定要存在 否则会抛出异常 这里的1.txt一定要存在
Files.copy(Paths.get("/home/project/1.txt"), Paths.get("/home/project/2.txt"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
}

编译运行:

1
2
$ javac CopyDemo.java
$ java CopyDemo

查看目录,如果没有报错,那么可以看到 1.txt 已经被复制了一份,叫做 2.txt。
(如果 1.txt 里面输入了内容 2.txt 也会存在)

移动和重命名

Files 类的 move(Path, Path, CopyOption… options) 方法移动文件或者目录,同样目标目录存在,那么比如使用REPLACE_EXISTING。 options 参数支持 StandardCopyOption 的以下枚举:

  • REPLACE_EXISTING:即使目标文件已存在,也执行移动。如果目标是符号链接,则替换符号链接,但它指向的内容不受影响。
  • ATOMIC_MOVE:将移动作为原子文件操作执行。如果文件系统不支持原子移动,则抛出异常。使用,ATOMIC_MOVE 您可以将文件移动到目录中,并保证观察目录的任何进程都可以访问完整的文件。

move 方法除了可以移动之外,也可以用与重命名。

编程实例

新建源代码文件 MoveDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class MoveDemo {
public static void main(String[] args) {
try {
//将1.txt 重命名为3.txt 如果只需要移动到不同的目录,文件名不变即可
Files.move(Paths.get("/home/project/1.txt"), Paths.get("/home/project/3.txt"), StandardCopyOption.REPLACE_EXISTING);

} catch (IOException e) {
e.printStackTrace();
}

}
}

编译运行:

1
2
$ javac MoveDemo.java
$ java MoveDemo

查看目录结构,可以看到之前的 1.txt 已经变成了 3.txt

删除

可以通过 Files 的 delete(Path path) 方法或者 deleteIfExists(Path path) 方法删除文件。

编程实例

新建源代码文件 DeleteDemo.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class DeleteDemo {
public static void main(String[] args) {
try {
//删除文件,文件必须存在,否则抛出异常
Files.delete(Paths.get("/home/project/3.txt"));
//删除文件,返回是否删除成功 即使文件不存在,也不会保存,直接返回false
System.out.println(Files.deleteIfExists(Paths.get("/home/project/3.txt")));
//或者使用File类的delete方法
File file = new File("/home/project/2.txt");
System.out.println(file.delete());
} catch (IOException e) {
e.printStackTrace();
}
}
}

编译运行:

1
2
3
4
$ javac DeleteDemo.java
$ java DeleteDemo
false
true

再次查看文件目录,2.txt 、3.txt 已经不存在了。

文件属性

Java 使用 File 类表示文件或者目录,可以通过 File 类获取文件或者目录的相关属性。

编程实例

新建源代码文件FileInfo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.io.File;
import java.util.Arrays;

public class FileInfo {
public static void main(String[] args) {
File file = new File("/home/project");
System.out.println("文件或者目录名:" + file.getName());
System.out.println("绝对路径:" + file.getAbsolutePath());
System.out.println("父目录:" + file.getParent());
System.out.println("文件路径:" + file.getPath());
//判断文件是否是目录
if (file.isDirectory()) {
//打印目录中的文件
Arrays.stream(file.list()).forEach(System.out::println);
}
System.out.println("是否隐藏:" + file.isHidden());
System.out.println("是否存在:" + file.exists());
}
}

上述代码,可以根据个人情况更换 File Path 直接获取结果

目录读取

Java 中读取目录中的文件可以直接使用 listFiles() 方法读取,但是也只能读取当前目录中的文件,如果当前目录中还有二级目录如何解决呢?三级目录呢?接下来将使用 Java 读取当前目录和子目录中的所有文件。

编程实例

新建源代码文件 ReadDir.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.File;
public class ReadDir {
public static void main(String[] args) {
readDir(new File("/home"));
}

public static void readDir(File file) {
if (file == null) {
return;
}
//如果当前file是目录
if (file.isDirectory()) {
File[] files;
//如果目录不为空
if ((files = file.listFiles()) != null) {
for (File file1 : files) {
//递归读取目录内容
readDir(file1);
}
}
} else {
//如果不是目录 直接输出文件名
System.out.println(file.getName());
}
}
}

上述代码,可以根据个人情况更换 File Path (注意 为了更好的效果最好是三级目录读取)