Java NIO Files类(java.nio.file.Files)提供了多种方法来处理文件系统中的文件。比直接使用File文件要方便的多了。
boolean exist = Files.exists(Paths.get(path));
boolean notExist = Files.notExists(Paths.get(path));
此方式删除文件或者空文件夹,如果文件夹不为空的情况下会报错
Files.delete(Paths.get(path));
Files.deleteIfExists(Paths.get(path));
Files.createDirectories(Paths.get(path));
Files.createFile(Paths.get(file));
List<String> list = new ArrayList<>();
list.add("this is title");
list.add("this is content");
Files.write(Paths.get(path), list, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
Files.write(Paths.get(path), "this is context".getBytes(), StandardOpenOption.APPEND, StandardOpenOption.CREATE);
StandardOpenOption.APPEND 追加写文件
StandardOpenOption.CREATE 如果文件不存在,则创建文件
该方法默认是使用UTF-8的字符集写入
如果JDK不是8而是JDK6,采用流的方式追加写文件
private void appendWriteFile(String file, List<String> list) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "GBK"));
for (String content : list) {
writer.write(content);
writer.newLine();
}
writer.flush();
} catch (Exception e) {
log.error("追加写文件失败!", e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
log.error("关闭流失败!", e);
}
}
}
}
List<String> list1 = Files.readAllLines(Paths.get("/path/file.txt"), StandardCharsets.UTF_8);
List<String> list2 = Files.readAllLines(Paths.get("/path/file.txt"), Charset.forName("UTF-8"));
List<String> list3 = Files.readAllLines(Paths.get("/path/file.txt"), Charset.defaultCharset());
第二个参数用来指定读取文件的字符集
该方法会将文件中的数据一次性都读取到内存中,如果文件特别大,或者处理的文件内容间没有依赖关系,可以选择一条一条读取并处理。
String file = "/path/file.txt";
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(reader);) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
使用Files.walk进行递归删除文件夹tmp3及其子文件夹
String path = "D:/tmp1/tmp2/tmp3";
Files.walk(Paths.get(path))
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
使用Files.walk进行递归删除文件夹tmp3下的所有文件及文件夹,tmp3不删除
String path = "D:/tmp1/tmp2/tmp3";
Files.walk(Paths.get(path))
.skip(1)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
使用Files.walkFileTree遍历文件夹进行删除文件夹内的所有文件
String path = "D:/tmp/tmp/0";
Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
// 在访问文件时触发该方法
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
System.out.printf("文件被删除 : %s%n", file);
return FileVisitResult.CONTINUE;
}
// 在访问子目录前触发该方法
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.printf("正在访问目录 : %s%n", dir);
return FileVisitResult.CONTINUE;
}
// 在访问目录之后触发该方法
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (!Paths.get(path).equals(Paths.get(dir.toUri()))) {
Files.delete(dir);
System.out.printf("文件夹被删除: %s%n", dir);
}
return FileVisitResult.CONTINUE;
}
// 在访问失败时触发该方法
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
// 写一些具体的业务逻辑
return super.visitFileFailed(file, exc);
}
}
);
使用Files.walkFileTree遍历文件夹删除整个文件夹
String path = "D:/tmp/tmp/0";
Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
// 在访问文件时触发该方法
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
System.out.printf("文件被删除 : %s%n", file);
return FileVisitResult.CONTINUE;
}
// 在访问子目录前触发该方法
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.printf("正在访问目录 : %s%n", dir);
return FileVisitResult.CONTINUE;
}
// 在访问目录之后触发该方法
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
System.out.printf("文件夹被删除: %s%n", dir);
return FileVisitResult.CONTINUE;
}
// 在访问失败时触发该方法
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
// 写一些具体的业务逻辑
return super.visitFileFailed(file, exc);
}
}
);
可以通过Files.walkFileTree很灵活的实现一些对文件或文件夹的操作,例如查找指定大小的文件,包含特殊字符的文件夹或文件等功能。
只要重写SimpleFileVisitor对象的四个方法即可。