文件删除时支持通配符 Java

Python011

文件删除时支持通配符 Java,第1张

package org.example

import java.io.File

import java.util.ArrayList

import java.util.List

import java.util.regex.Matcher

import java.util.regex.Pattern

public class FileUtil {

/**

* 删除指定目录下符合指定<param>pattern</param>的文件或目录

* @param path

* 指定的目录

* @param pattern

* 要删除的目标,可以含通配符(*)

* 如:x*d\*.bak,为指定目录下以x开头d结尾的目录下的所有bak文件

* @return

* true, 没有错误;false, 发生了错误

*/

public static boolean delete(String path, String pattern) throws Exception {

if( path == null || pattern == null )

throw new IllegalArgumentException("参数为空")

boolean result = true

File root = new File(path)

if( !root.isDirectory() || !root.exists() )

throw new IllegalArgumentException("不是目录或者目录不存在")

List<File>folderBuffer = new ArrayList<File>()

folderBuffer.add(root)

String[] ps = pattern.split("\\" + File.separator)

for(int i = 0i <ps.lengthi ++) {

List<File>tmpList = new ArrayList<File>()

while(folderBuffer.size() >0) {

File folder = folderBuffer.remove(0)

List<File>fileMatched = applyPattern(folder, ps[i])

tmpList.addAll(fileMatched)

}

folderBuffer.addAll(tmpList)

if( folderBuffer.size() == 0 )

return true

}

for(int i = 0i <folderBuffer.size()i ++) {

boolean r = deleteFile(folderBuffer.get(i))

if( !r )

return r

}

return result

}

private static boolean deleteFile(File f) {

trace("DELETE: " + f.getPath())

if( f.isFile() )

return f.delete()

// 目录也有可能满足通配符!

// 是否执行删除带有文件的目录?自己判断,这里直接删,不管成功失败

return f.delete()

}

/**

* 将含通配符(*)的字符串转变成正则表达式

* @param pattern

* @return

* @remark

* 这里做得比较简单,只是替换了"."和"*",实际情况可能还有其他字符需要替换

*/

private static Pattern createPattern(String pattern) {

String _pattern = pattern.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*")

Pattern p = Pattern.compile(_pattern, Pattern.CASE_INSENSITIVE)

return p

}

private static List<File>applyPattern(File folder, String pattern) {

List<File>list = new ArrayList<File>()

if( folder == null || folder.isFile() || pattern == null )

return list// 空List

Pattern p = createPattern(pattern)

File[] files = folder.listFiles()

for(int i = 0i <files.lengthi ++) {

File file = files[i]

String name = file.getName()

Matcher m = p.matcher(name)

if( m.matches() ) {

list.add(file)

trace("[ M] Folder: " + folder + ", Pattern: " + pattern +

", File: " + name + " <-----Matched----")

}

else {

trace("[NM] Folder: " + folder + ", Pattern: " + pattern +

", File: " + name)

}

}

return list

}

private static void trace(String message) {

System.out.println(message)

}

public static void main(String[] args) throws Exception {

trace("警告:请按照您自己的要求修改程序,风险自负。")

FileUtil.delete("F:\\temp", "*x1\\*.exe")

}

}

首先泛型是用来约束的(或者说是规范化),泛型的本质是参数化类型,不是用来通配的(这个说法也不完全对),这个概念一定不要混淆了。

你添加的元素是String类型的,那么你的代码就得这样:

ArrayList<String> arr = new ArrayList<String>()

或者:

List<String> arr = new ArrayList<String>()  // 多态,推荐使用

再或者:

List arr = new ArrayList()

ArrayList arr = new ArrList() // 这两种没有用泛型,编译器会提示警告

用上面1和2方式的话,你的arr集合就只能存放String类型对象,3没有用泛型,什么类型的对象都可以存放。只是取出来的时候,会要类型转换,这个过程很容易出错。

希望我的回答能对你有所帮助,荣幸之至。

这是泛型嘛,泛型简单的意思就是说,你不知道你想要的这个类具体是啥,但是你可以知道这个类的相关子类或者父类

所以从上面的观点来看,<? extends A>和 <T extends A>是没啥区别的

例如下面这个两个方法表达的意思是一样的,都表示参数是一个集合,这个集合可能包含着A或者A的任何子类

public void someMethod(List<? extends A> list)

public void someMethod(List<T extends A> list)

这是一种情况,但是相比而言,一个类中,多处方法都需要这个泛型的时候,<T extends A>要比<? extends A>方便的多,就像在代码里,你声明了一个变量后,你就可以在这个变量的代码块里任何地方调用,同理<T extends A>就像是声明了一个泛型变量T,这个T是一个A或者A的子类,然后这个变量T在所能用的范围之内,你都可以直接用T表示,不用再写<? extends A>或者<T extends A>,比如:

// 前面定义了T,后面参数就可以用T表示了

public <T extends A>void some(List<T> t)

上面是方法里,这个范围比较窄,放在类里,效果更明显,比如:

public class B<T extends A>{

    // 一个A类或者A子类的变量

    private T a

    

    // 一个方法

    public void some(List<T> list)

}

所以可以看到,差别也不太大