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,一经查实,立即删除!

相关文章

实现小程序canvas拖拽功能

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

H5页面滚动阻尼效果实现

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

web 前端 html

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

再谈前后端分离

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

Python - day1 借鉴洪卫

一、了解开发语言 1、高级语言:Python,Java,C,C#,PHP,JS,Go,Ruby,SQL,Swift,Perl,Objective-C,R等等; 2、低级…

返回一个二维整数数组最大子数组的和

要求: 1,输入一个二维整形数组,数组里有正数也有负数。 2,二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和, 3,求所有子数组的和的最大值。 设计思路: 参照一维整数数组求解最大…

基于React的表单开发的分析(上)

本文主要讲解后台系统与表单相关的页面开发,并分析如何才能更好地、高效地开发。 技术栈 ReactAntd 背景 Antd 以下我都将Ant Design 简称为 Antd Ant Design是个服务于企业级产品的UI框架,主要可以用于中后台系统,它有基于React、Vue和Angular的实现…

50个Servlet面试问答

Servlet是Java EE的一个非常重要的主题,所有Web应用程序框架(例如Spring和Struts)都建立在它之上。 这使servlet成为Java访谈中的热门话题。 在这里,我提供了50个servlet面试问题的列表,并提供了答案,以帮…

深入浅出的webpack4构建工具--webpack4+react构建环境(二十)

下面我们来配置下webpack4react的开发环境,之前都是针对webpack4vue的。下面我们也是在之前项目结构的基础之上进行配置下。 首先看下如下是我为 webpack4react 基本的项目结构如下: ### 目录结构如下: demo1 …

Webpack 4进阶--从前的日色变得慢 ,一下午只够打一次包

从前的日色变得慢,车,马,邮件都慢,一生只够爱一个人 -- 《从前慢》 近期在团队项目里把Webpack升级到4.4.1,过程中发现现存的升级文档十分有限,踩了不少坑,好在升级之后提升还算显著&#xff0c…

编码Java时的10个微妙的最佳实践

这是10个最佳实践的列表,这些最佳实践比您的平均Josh Bloch有效Java规则要微妙得多。 尽管Josh Bloch的列表很容易学习,并且涉及日常情况,但此处的列表包含了涉及API / SPI设计的较不常见的情况,但可能会产生很大的影响。 我在编…

Vue 实现微信 jssdk 扫码, 上传图片

流程 1: 配置微信公众号JS域名 2:前端发送URL后台获取JSSDK配置, 后台Service代码如下, 修改2处位置: WeixinUtil.APPID > 当前公众号APPID WeixinUtil.getAccessToken() > 当前公众号access_token public interface IWxJssdkService {Map<String, Object> getJssd…

使用Storm进行可扩展的实时状态更新

在本文中&#xff0c;我将说明如何借助Storm框架以可扩展且无锁定的方式在数据库中维护实时事件驱动流程的当前状态。 Storm是基于事件的数据处理引擎。 它的模型依赖于基本原语&#xff0c;例如事件转换&#xff0c;过滤&#xff0c;聚合……&#xff0c;我们将它们组合成拓扑…

【干货】十分钟读懂浏览器渲染流程

在之前写过的一篇《"天龙八步"细说浏览器输入URL后发生了什么》一文中&#xff0c;和大家分享了从在浏览器中输入网址URL到最终页面展示的整个过程。部分读者向我反馈对于最后的浏览器渲染布局这块不是很清晰&#xff0c;所以本文就浏览器渲染流程单独开篇讲解&#…

控制台资费管理主菜单java_java毕业设计_springboot框架的高速公路收费管理系统...

今天介绍一个java毕设题目, 题目内容为springboot框架的高速公路收费管理系统, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 高速公路收费管理系统的信息存储于mysql中, 并基于mybatis进行了orm封装, 该高速公路收费管理…

在Amazon EMR上运行Hadoop MapReduce作业

不久前&#xff0c;我发布了如何使用CLI设置EMR群集的信息。 在本文中&#xff0c;我将展示如何使用适用于AWS的Java SDK来设置集群。 展示如何使用Java AWS开发工具包执行此操作的最佳方法是展示完整的示例&#xff0c;因此&#xff0c;让我们开始吧。 设置一个新的Maven项目…

[JSConf EU 2018] 大脑控制 Javascript

先解释&#xff0c;本人为前端菜鸟&#xff0c;之前也未参加过类似的活动&#xff0c;没有翻译过什么文章&#xff0c;此次是好奇心使然&#xff0c;也是想尝试下&#xff0c;学习学习&#xff0c;英文很烂&#xff0c;全靠有道&#xff0c;但是视频整个看下来&#xff0c;还是…

JavaScript中不得不说的断言?

断言主要应用于“调试”与“测试” 一、前端中的断言 仔细地查找一下JavaScript中的API&#xff0c;实际上并没有多少关于断言的方法。唯一一个就是console.assert&#xff1a; // console.assert(condition, message)const a 1console.assert(typeof a number, a should be…

Java EE状态会话Bean(EJB)示例

在本文中&#xff0c;我们将了解如何在简单的Web应用程序中使用状态会话Bean来跟踪客户端会话中的状态。 1.简介 有状态会话Bean通常保存有关特定客户端会话的信息&#xff0c;并在整个会话中保留该信息&#xff08;与无状态会话Bean相对&#xff09;。 有状态EJB实例仅与一个…

起点海外版 Hybrid App-内嵌页优化实践

本文作者&#xff1a;刘文涛 原创声明&#xff1a;本文为阅文前端团队 YFE 成员出品&#xff0c;请尊重原创&#xff0c;转载请联系公众号 (id: yuewen_YFE) 获取授权&#xff0c;并注明作者、出处和链接。 今年年初我司开启了起点品牌的海外之旅&#xff0c;名为「 Webnovel 」…