java 中io的删除文件_总结删除文件或文件夹的7种方法-JAVA IO基础总结第4篇

c8810c7ad3723e76a82a1953bdcb0b75.png

本文是Java IO总结系列篇的第4篇,前篇的访问地址如下:

如果您阅读完成,觉得此文对您有帮助,请给我点个赞,您的支持是我不竭的创作动力。

为了方便大家理解,我特意制作了本文对应的视频:总结删除文件或者文件夹的7种方法

一、删除文件或文件夹的四种基础方法

下面的四个方法都可以删除文件或文件夹,它们的共同点是:当文件夹中包含子文件的时候都会删除失败,也就是说这四个方法只能删除空文件夹。

需要注意的是:传统IO中的File类和NIO中的Path类既可以代表文件,也可以代表文件夹。

File类的delete()

File类的deleteOnExit()

Files.delete(Path path)

Files.deleteIfExists(Path path);

它们之间的差异:

f099e9fe1b12d5c82402b92e42a3f1b3.png

由上面的对比可以看出,传统IO方法删除文件或文件夹,再删除失败的时候,最多返回一个false。通过这个false无法发掘删除失败的具体原因,是因为文件本身不存在删除失败?还是文件夹不为空导致的删除失败?

NIO 的方法在这一点上,就做的比较好,删除成功或失败都有具体的返回值或者异常信息,这样有利于我们在删除文件或文件夹的时候更好的做程序的异常处理

需要注意的是传统IO中的deleteOnExit方法,笔者觉得应该避免使用它。它永远只返回void,删除失败也不会有任何的Exception抛出,所以我建议不要用,以免在你删除失败的时候没有任何的响应,而你可能误以为删除成功了。

//false只能告诉你失败了 ,但是没有给出任何失败的原因

@Test

void testDeleteFileDir1() {

File file = new File("D:\\data\\test");

boolean deleted = file.delete();

System.out.println(deleted);

}

//void ,删除失败没有任何提示,应避免使用这个方法,就是个坑

@Test

void testDeleteFileDir2() {

File file = new File("D:\\data\\test1");

file.deleteOnExit();

}

//如果文件不存在,抛出NoSuchFileException

//如果文件夹里面包含文件,抛出DirectoryNotEmptyException

@Test

void testDeleteFileDir3() throws IOException {

Path path = Paths.get("D:\\data\\test1");

Files.delete(path); //返回值void

}

//如果文件不存在,返回false,表示删除失败(文件不存在)

//如果文件夹里面包含文件,抛出DirectoryNotEmptyException

@Test

void testDeleteFileDir4() throws IOException {

Path path = Paths.get("D:\\data\\test1");

boolean result = Files.deleteIfExists(path);

System.out.println(result);

}

归根结底,建议大家使用java NIO的Files.delete(Path path)和Files.deleteIfExists(Path path);进行文件或文件夹的删除。

二、如何删除整个目录或者目录中的部分文件

上文已经说了,那四个API删除文件夹的时候,如果文件夹包含子文件,就会删除失败。那么,如果我们确实想删除整个文件夹,该怎么办?

前提准备

为了方便我们后面进行试验,先去创建这样一个目录结构,“.log”结尾的是数据文件,其他的是文件夹

3a45c4e03569f81278f50d0a06cf8b3b.png

可以使用代面的代码进行创建

private void createMoreFiles() throws IOException {

Files.createDirectories(Paths.get("D:\\data\\test1\\test2\\test3\\test4\\test5\\"));

Files.write(Paths.get("D:\\data\\test1\\test2\\test2.log"), "hello".getBytes());

Files.write(Paths.get("D:\\data\\test1\\test2\\test3\\test3.log"), "hello".getBytes());

}

2.1. walkFileTree与FileVisitor

使用walkFileTree方法遍历整个文件目录树,使用FileVisitor处理遍历出来的每一项文件或文件夹

FileVisitor的visitFile方法用来处理遍历结果中的“文件”,所以我们可以在这个方法里面删除文件

FileVisitor的postVisitDirectory方法,注意方法中的“post”表示“后去做……”的意思,所以用来文件都处理完成之后再去处理文件夹,所以使用这个方法删除文件夹就可以有效避免文件夹内容不为空的异常,因为在去删除文件夹之前,该文件夹里面的文件已经被删除了。

@Test

void testDeleteFileDir5() throws IOException {

createMoreFiles();

Path path = Paths.get("D:\\data\\test1\\test2");

Files.walkFileTree(path,

new SimpleFileVisitor() {

// 先去遍历删除文件

@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 postVisitDirectory(Path dir,

IOException exc) throws IOException {

Files.delete(dir);

System.out.printf("文件夹被删除: %s%n", dir);

return FileVisitResult.CONTINUE;

}

}

);

}

下面的输出体现了文件的删除顺序

文件被删除 : D:\data\test1\test2\test2.log

文件被删除 : D:\data\test1\test2\test3\test3.log

文件夹被删除 : D:\data\test1\test2\test3\test4\test5

文件夹被删除 : D:\data\test1\test2\test3\test4

文件夹被删除 : D:\data\test1\test2\test3

文件夹被删除 : D:\data\test1\test2

我们既然可以遍历出文件夹或者文件,我们就可以在处理的过程中进行过滤。比如:

按文件名删除文件或文件夹,参数Path里面含有文件或文件夹名称

按文件创建时间、修改时间、文件大小等信息去删除文件,参数BasicFileAttributes 里面包含了这些文件信息。

2.2.Files.walk

如果你对Stream流语法不太熟悉的话,这种方法稍微难理解一点,但是说实话也非常简单。

使用Files.walk遍历文件夹(包含子文件夹及子其文件),遍历结果是一个Stream

对每一个遍历出来的结果进行处理,调用Files.delete就可以了。

@Test

void testDeleteFileDir6() throws IOException {

createMoreFiles();

Path path = Paths.get("D:\\data\\test1\\test2");

try (Stream walk = Files.walk(path)) {

walk.sorted(Comparator.reverseOrder())

.forEach(DeleteFileDir::deleteDirectoryStream);

}

}

private static void deleteDirectoryStream(Path path) {

try {

Files.delete(path);

System.out.printf("删除文件成功:%s%n",path.toString());

} catch (IOException e) {

System.err.printf("无法删除的路径 %s%n%s", path, e);

}

}

问题:怎么能做到先去删除文件,再去删除文件夹? 。 利用的是字符串的排序规则,从字符串排序规则上讲,“D:\data\test1\test2”一定排在“D:\data\test1\test2\test2.log”的前面。所以我们使用“sorted(Comparator.reverseOrder())”把Stream顺序颠倒一下,就达到了先删除文件,再删除文件夹的目的。

下面的输出,是最终执行结果的删除顺序。

删除文件成功:D:\data\test1\test2\test3\test4\test5

删除文件成功:D:\data\test1\test2\test3\test4

删除文件成功:D:\data\test1\test2\test3\test3.log

删除文件成功:D:\data\test1\test2\test3

删除文件成功:D:\data\test1\test2\test2.log

删除文件成功:D:\data\test1\test2

2.3.传统IO-递归遍历删除文件夹

传统的通过递归去删除文件或文件夹的方法就比较经典了

//传统IO递归删除

@Test

void testDeleteFileDir7() throws IOException {

createMoreFiles();

File file = new File("D:\\data\\test1\\test2");

deleteDirectoryLegacyIO(file);

}

private void deleteDirectoryLegacyIO(File file) {

File[] list = file.listFiles(); //无法做到list多层文件夹数据

if (list != null) {

for (File temp : list) { //先去递归删除子文件夹及子文件

deleteDirectoryLegacyIO(temp); //注意这里是递归调用

}

}

if (file.delete()) { //再删除自己本身的文件夹

System.out.printf("删除成功 : %s%n", file);

} else {

System.err.printf("删除失败 : %s%n", file);

}

}

需要注意的是:

listFiles()方法只能列出文件夹下面的一层文件或文件夹,不能列出子文件夹及其子文件。

先去递归删除子文件夹,再去删除文件夹自己本身

欢迎关注我的博客,里面有很多精品合集

本文转载注明出处(必须带连接,不能只转文字):字母哥博客。

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Koa2和Redux中间件源码研究

一、Koa2中间件源码分析 在Koa2中,中间件被存放在一个数组中。 使用koa中,最常见的就是app.use(fn),use函数部分源码如下所示。首先中间件必须是个函数。若是generator函数,则需要进行转化。最后把该中间件推入middelaware数组中…

Web应用程序的简单插件系统

我们需要制作多个具有很多共享功能的基于Web的项目。 为此,某种插件系统将是一个不错的选择(作为复制粘贴内容的替代方法)。 有些框架(例如grails)可以选择制作Web插件,但大多数没有,因此需要实…

[转]C++ auto 关键字的使用

原文地址: https://www.cnblogs.com/KunLunSu/p/7861330.html C98 auto 早在C98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期,这是多余的,因为就算不使用auto声明,变量依…

python模块之configparser

一 什么是configparser? configparser是用于解析配置文件的模块。什么是配置文件呢?包含配置程序信息的文件就称为配置文件。什么样的数据应该作为配置信息呢?需要修改但是不经常改的信息就可以作为配置信息,比如数据文件的路径。…

java的使用条件_Java使用条件语句和循环结构确定控制流

与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流。本文将简单讲解条件、循环和switch。一、块作用域块(block),即复合语句。是指由一对大括号括起来的若干条简单的Java语句。块确定了变量的作用域。比如:public class Code {st…

实现小程序canvas拖拽功能

组件地址 https://github.com/jasondu/wx-comp-canvas-drag 实现效果 如何实现 使用canvas使用movable-view标签 由于movable-view无法实现旋转,所以选择使用canvas 需要解决的问题 如何将多个元素渲染到canvas上如何知道手指在元素上、如果多个元素重叠如何知…

探索Apache Camel Core – Seda组件

Apache Camel中的seda组件与我在之前的博客中介绍的direct组件非常相似,但是以异步的方式。 为此,它使用java.util.concurrent.BlockingQueue作为默认实现来使消息排队并与主Route线程断开连接,然后在单独的线程中处理消息。 由于此BlockingQ…

Properties类和如何操作属性

Properties类继承关系java.lang.Object java.util.Dictionary<K,V> java.util.Hashtable<Object,Object> java.util.Properties所有已实现的接口&#xff1a; Serializable, Cloneable, Map<Object,Object> 直接已知子类&#xff1a; Provide…

Spring MVC:带有CNVR卷的REST应用程序。 2

在上一篇文章中&#xff0c;我快速概述了带有CNVR的Spring MVC REST项目的设置环境。 在这一部分中&#xff0c;我可以直接关注控制器和REST服务的演示。 通常&#xff0c;我将做一个简短的介绍&#xff0c;然后我将介绍控制器方法并解释所有关键时刻。 由于我将进一步讨论RES…

SCP 报错 not a regular file

在 scp 后 加 -r转载于:https://www.cnblogs.com/LYliangying/p/9815534.html

H5页面滚动阻尼效果实现

功能描述 要求 页面分为AB两个区域 当手机可视区的底部接触到 “阻尼带” 的时候&#xff0c;有个上拉弹性过程 当上拉到一定阈值程度就直接把B区顶部弹到手机可视区的顶部&#xff0c;让可视区从B区开始显示当上拉程度未到阈值&#xff0c;就回弹复原 当手机可视区从B区向上…

java面试题(杨晓峰)---第五讲String、StringBuffer、StringBuilder有什么区别?

线程 字符 操作频繁度 1 String &#xff08;1&#xff09;String的创建机制 由于String在java世界中使用过于频繁&#xff0c;java为了避免在一个系统中产生大量重复的String对象&#xff0c;引入了字符串常量池&#xff0c;其运行机制是&#xff1a;创建一个字符串时&am…

mysql怎么按年份分组_mysql - MYSQL按ID分组,但根据最近的年份进行拉取 - SO中文参考 - www.soinside.com...

我有一个包含以下内容的表&#xff1a;StudID Name Year SubjectID SubjectName MTFlag51280 ALOYSIUS 2019 42 CHINESE LANGUAGE 151280 ALOYSIUS 2020 70 ENGLISH LANGUAGE 051280 ALOYSIUS 2020 95 CHINESE B 151280 ALOYSIUS 2020 75 MATHEMATICS 051290 AMIL 2020 70 ENGL…

面向 Web 前端的原生语言总结手册

这一系列文章旨在让具有 Web 前端背景的开发者快速上手原生语言。 背景与动机 从 WebView 到 Hybrid 再到 React Native&#xff0c;移动端主流技术方案中前端同学的施展空间越来越大。但传统 Web 前端背景的同学所熟悉的编程语言主要是 JavaScript&#xff0c;在与 Native 协…

Java 8的新增功能(第二部分–可能会出现什么)

免责声明&#xff1a;我不为Oracle工作&#xff0c;也不以任何方式代表Oracle。 此功能列表不是官方的。 作为“局外人”&#xff0c;这只是我研究的一部分。 这是由三部分组成的系列文章的第二部分。 在第一部分中 &#xff0c;我谈到了Oracle正式让开发人员知道JavaFX 8中应…

MariaDB卸载

二进制安装方式的MariaDB卸载 关闭mysql服务service mysql stop 或 /etc/init.d/mysql stop 或 mysqladmin shutdown -uroot -p 删除数据文件和目录whereis mysql find / -name mysql rm -rf xxx 删除软链接&#xff0c;二进文件&#xff08;如有必要&#xff09;cd /usr/local…

aix系统java堆_浅谈AIX环境下的Java性能调优

1、什么是JavaJava 是一种面向对象的编程语言。它以 C 为模型&#xff0c;被设计成小的、简单的、在源和二进制级别跨平台的可移植的语言&#xff0c;Java 程序(applets 和应用程序)可以运行于任何已经安装了 Java 虚拟机(JVM)的机器上。Java 相对其它计算机语言有显著的优势&a…

web 前端 html

1&#xff0c;什么是web 在网络中&#xff0c;大量的数据需要有一个载体&#xff0c;而很多人都能够访问这个载体&#xff0c;利用浏览器的这个窗口链接一个有一个载体&#xff0c;这个载体就是网站也就是web的前身。  1&#xff0c;web标准&#xff1a;结构标准&#xff0c;表…

cf 1060e 树形dp 树上任意两点的距离和

题意&#xff1a; 给出一个树&#xff0c;把树上任意两个相隔一个点的点加一条边&#xff0c;问加完边之后任意两点的距离和是多少. 参考博客 &#xff1a;https://blog.csdn.net/Mr_Treeeee/article/details/82960566 思路&#xff1a;枚举边的贡献 算出所有点与点之间的距离&…

再谈前后端分离

前段时间我针对手头上的项目前端配置进行了反思以及总结并且写了两篇文章: webpack传统后端渲染的项目前端配置, webpack配置之前后端不分离, 很显然这些配置能满足一时的需求, 但是也有不足. 今天继续总结, 这里应该不涉及到具体后端语言, 只对前端配置进行描述. 毕竟配置工程…