用途:文件工具类(文件常用操作)
使用场景
提供100多个文件常用操作方法,包含并不局限于:判断文件或文件夹是否为空、判断file是否为文件或文件夹、递归文件夹里的所有文件、获取指定文件夹的所有文件名、获取临时文件夹或临时文件的内容或者路径、计算文件夹或文件的总大小、创建文件或文件夹、创建临时文件或临时文件夹、删除文件或文件夹、修改文件名或文件夹名、复制文件或文件夹、移动文件或文件夹、清空文件夹、获取规范的绝对路径、比较两个文件、判断文件是否被改动、获取父路径或子路径、获取主文件名或后缀名等
项目引用
此博文的依据:hutool-5.6.5版本源码
参考案例:
//目录:里面没有文件时为空 //文件:文件大小为0时为空 Assert.assertEquals(Boolean.TRUE,FileUtil.isEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\fileTest"))); Assert.assertEquals(Boolean.FALSE,FileUtil.isEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\copyTest1.txt"))); Assert.assertEquals(Boolean.TRUE,FileUtil.isEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\isEmptyTest.txt")));
参考案例:
Assert.assertEquals(Boolean.FALSE,FileUtil.isNotEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\fileTest"))); Assert.assertEquals(Boolean.TRUE,FileUtil.isNotEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\copyTest1.txt"))); Assert.assertEquals(Boolean.FALSE,FileUtil.isNotEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\isEmptyTest.txt")));
参考案例:
//一定要是目录file不然会抛异常 Assert.assertEquals(Boolean.TRUE,FileUtil.isDirEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\fileTest"))); Assert.assertEquals(Boolean.FALSE,FileUtil.isDirEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu"))); //抛异常 cn.hutool.core.io.IORuntimeException: NotDirectoryException: Assert.assertEquals(Boolean.FALSE,FileUtil.isDirEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\isEmptyTest.txt")));
返回值:
文件列表
参考案例:
//递归遍历目录以及子目录中的所有文件 可以加过滤条件 List<File> files = FileUtil.loopFiles(new File("C:\\Users\\Administrator\\Desktop\\xuzhu"), new FileFilter() { @Override public boolean accept(File pathname) { if(pathname.getName().indexOf("to")>-1){ return true; }else{ return false; } } }); for(File file:files){ System.out.println(file.getName()); }
方法明细
方法名称:cn.hutool.core.io.FileUtil.loopFiles(java.io.File, int, java.io.FileFilter)
方法描述
递归遍历目录以及子目录中的所有文件<br>
如果提供file为文件,直接返回过滤结果
支持版本及以上
4.6.3
参数描述:
//递归遍历目录以及子目录中的所有文件 可以加过滤条件 List<File> files = FileUtil.loopFiles(new File("C:\\Users\\Administrator\\Desktop\\xuzhu"),3, new FileFilter() { @Override public boolean accept(File pathname) { if(pathname.getName().indexOf("to")>-1){ return true; }else{ return false; } } }); for(File file:files){ System.out.println(file.getName()); }
//创建File对象,此方法会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/ File srcFile = FileUtil.file(new File("C:\\Users\\Administrator\\Desktop\\xuzhu"),"contentEqualsIgnoreEOLTest1.txt"); Assert.assertEquals(Boolean.TRUE,srcFile.exists()); //莫须有的父目录,应该找不到此文件 srcFile = FileUtil.file(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\aaa"),"contentEqualsIgnoreEOLTest1.txt"); Assert.assertEquals(Boolean.FALSE,srcFile.exists());
//创建File对象,此方法会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/ File srcFile = FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu","loopFileTest","loopFileTest1","toLoopFlie1.txt"); Assert.assertEquals(Boolean.TRUE,srcFile.exists());
//创建File对象,多层文件的文件名,由外到内依次传入 File srcFile = FileUtil.file("C:","Users","Administrator","Desktop","xuzhu","loopFileTest","loopFileTest1","toLoopFlie1.txt"); Assert.assertEquals(Boolean.TRUE,srcFile.exists()); srcFile = FileUtil.file("C:","Users","Administrator","Desktop","xuzhu_nb","loopFileTest","loopFileTest1","toLoopFlie1.txt"); Assert.assertEquals(Boolean.FALSE,srcFile.exists());
//创建所给文件或目录的父目录,返回父目录 // 注:与touch差别,这个只会创建父目录,文件不会帮忙创建 File file = FileUtil.mkParentDirs(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\mkParentDirs\\mkParentDirsTest.txt")); System.out.println("文件名称:"+file.getName()); Assert.assertEquals(Boolean.TRUE,FileUtil.exist(file));
//创建所给文件或目录的父目录,返回父目录 // 注:与touch差别,这个只会创建父目录,文件不会帮忙创建 File file = FileUtil.mkParentDirs("C:\\Users\\Administrator\\Desktop\\xuzhu\\mkParentDirs\\mkParentDirsTest.txt"); System.out.println("文件名称:"+file.getName()); Assert.assertEquals(Boolean.TRUE,FileUtil.exist(file));
//清理空文件夹 此文件夹包含一个空文件夹,一个非空文件夹和一个文件 boolean result = FileUtil.cleanEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\cleanEmptyTest\\")); Assert.assertTrue(result);
//清理空文件夹 传入的文件夹本身就是空的,删除这个文件夹 boolean result = FileUtil.cleanEmpty(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\cleanEmptyTest1\\")); Assert.assertTrue(result);
//copyTest1.txt存在,copyTest2.txt不存在 String srcPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest\\copyTest1.txt"; String destPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest\\copyTest2.txt"; //返回目标dest的file 复制操作 //StandardCopyOption.COPY_ATTRIBUTES:完整复制源文件属性到新文件 注意:目标文件一定不能存在,不然会报错(FileAlreadyExistsException: ***) File copyFile = FileUtil.copyFile(srcPath,destPath, StandardCopyOption.COPY_ATTRIBUTES); Assert.assertEquals(Boolean.TRUE,copyFile.exists());
参考案例2:
//copyTest1.txt存在,copyTest2.txt,copyTest3.txt不存在 String srcPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest1.txt"; String destPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest2.txt"; String destPath3 = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest3.txt"; //返回目标dest的file 复制操作 File copyFile = FileUtil.copyFile(srcPath,destPath, StandardCopyOption.COPY_ATTRIBUTES); FileUtil.copyFile(srcPath,destPath3, StandardCopyOption.COPY_ATTRIBUTES); Assert.assertEquals(Boolean.TRUE,copyFile.exists()); //如果目标路径已经存在(也就是copyTest2.txt文件),那么复制或者移动将失败。 // 如果想要覆盖已经存在的目标路径,可以使用REPLACE_EXISTING选项。如果想要复制所有文件的属性,可以使用COPY_ATTRIBUTES选项。也可以同时使用两个选项 srcPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest1.txt"; destPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest2.txt"; copyFile = FileUtil.copyFile(srcPath,destPath, StandardCopyOption.REPLACE_EXISTING); Assert.assertEquals(Boolean.TRUE,copyFile.exists()); srcPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest1.txt"; destPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest1\\copyTest3.txt"; copyFile = FileUtil.copyFile(srcPath,destPath, StandardCopyOption.REPLACE_EXISTING,StandardCopyOption.COPY_ATTRIBUTES); Assert.assertEquals(Boolean.TRUE,copyFile.exists());
//copyTest1.txt存在,copyTest2.txt不存在 String srcPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest2\\copyTest1.txt"; String destPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest2\\copyTest2.txt"; //返回目标dest的file 复制操作 //StandardCopyOption.ATOMIC_MOVE:将文件作为原子文件系统操作移动 会报错:(UnsupportedOperationException: Unsupported copy option)因为copy方法不能用这个参数 //说到这个顺便说明下,copy支持的属性有:(详见:WindowsFileCopy.java) // StandardCopyOption.REPLACE_EXISTING // LinkOption.NOFOLLOW_LINKS // StandardCopyOption.COPY_ATTRIBUTES // ExtendedCopyOption.INTERRUPTIBLE File copyFile = FileUtil.copyFile(srcPath,destPath, StandardCopyOption.ATOMIC_MOVE); Assert.assertEquals(Boolean.TRUE,copyFile.exists());
//copyTest1.txt存在,copyTest2.txt不存在 String srcPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest3\\copyTest1.txt"; String destPath = "C:\\Users\\Administrator\\Desktop\\xuzhu\\copyFileTest3\\copyTest2.txt"; //返回目标dest的file 复制操作 //StandardCopyOption.COPY_ATTRIBUTES:完整复制源文件属性到新文件 注意:目标文件一定不能存在,不然会报错(FileAlreadyExistsException: ***) File copyFile = FileUtil.copyFile(new File(srcPath),new File(destPath), StandardCopyOption.COPY_ATTRIBUTES); Assert.assertEquals(Boolean.TRUE,copyFile.exists());
FileUtil.rename(FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\renameTest\\hutool.jpg"), "hutool2.jpg", false);
返回值:
目标文件
参考案例:
//isRetainExt 是否保留原文件的扩展名,如果保留,则newName不需要加扩展名 FileUtil.rename(FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\renameTest3\\hutool.jpg"), "hutool2",Boolean.TRUE, false); FileUtil.rename(FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\renameTest3\\hutool1.jpg"), "hutool3.jpg",Boolean.FALSE, false);
//获取规范的绝对路径 System.out.println(FileUtil.getCanonicalPath(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\copyTest1.txt"))); //如果传入file为null,返回null File file = null; System.out.println(FileUtil.getCanonicalPath(file)); //如果传入不存在路径,也是能取到的 System.out.println(FileUtil.getCanonicalPath(new File("C:\\Users\\Administrator\\Desktop\\getCanonicalPathTest\\copyTest1.txt")));
参考案例:
//修复后的路径 String path = FileUtil.normalize("C:\\Users\\Administrator\\Desktop\\xuzhu\\isAbsolutePathTest\\isAbsolutePathTest.txt"); //是否已经是绝对路径 Assert.assertEquals(Boolean.TRUE,FileUtil.isAbsolutePath(path)); path = FileUtil.normalize("FileUtil.class"); //是否已经是绝对路径 Assert.assertEquals(Boolean.FALSE,FileUtil.isAbsolutePath(path));
// 比较两个文件内容是否相同,不能比较两个文件夹,方法里有做判断是否是文件夹,是的话报错提示 // 源文件存在,目标文件不存在 File srcFile1 = FileUtil.file("hutool.jpg"); File destFile1 = FileUtil.file("d:/hutool.jpg"); Assert.assertEquals(Boolean.FALSE,FileUtil.contentEqualsIgnoreEOL(srcFile1, destFile1, CharsetUtil.CHARSET_UTF_8)); // 源文件存在,目标文件存在 File srcFile2 = FileUtil.file("hutool.jpg"); File destFile2 = FileUtil.file("hutool.jpg"); Assert.assertEquals(Boolean.TRUE,FileUtil.contentEqualsIgnoreEOL(srcFile2, destFile2,CharsetUtil.CHARSET_UTF_8)); // 源文件存在,目标文件存在 File srcFile3 = FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\copyTest1.txt"); File destFile3 = FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\toCopyTest1.txt"); Assert.assertEquals(Boolean.TRUE,FileUtil.contentEqualsIgnoreEOL(srcFile3, destFile3,CharsetUtil.CHARSET_UTF_8));
String dir = "d:\\aaa\\bbb\\cc\\ddd"; int index = FileUtil.lastIndexOfSeparator(dir); Assert.assertEquals(13, index); String file = "ddd.jpg"; int index2 = FileUtil.lastIndexOfSeparator(file); Assert.assertEquals(-1, index2);
File srcFile = FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\convertLineSeparatorTest.txt"); File convertLineSeparatorFile = FileUtil.convertLineSeparator(srcFile, CharsetUtil.CHARSET_UTF_8, LineSeparator.WINDOWS); InputStream input = null; try { //创建流 input = new FileInputStream(convertLineSeparatorFile); String str = IoUtil.read(input,CharsetUtil.CHARSET_UTF_8); System.out.println(str); } catch (IOException e) { //抛出一个运行时异常(直接停止掉程序) throw new RuntimeException("运行时异常",e); } finally { IoUtil.close(input); }
//检查父完整路径是否为自路径的前半部分,如果不是说明不是子路径,可能存在slip注入,此方法会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/ File srcFile = FileUtil.checkSlip(new File("C:\\Users\\Administrator\\Desktop\\xuzhu"),new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\contentEqualsIgnoreEOLTest1.txt")); Assert.assertEquals(Boolean.TRUE,srcFile.exists());
参考案例2:
//检查父完整路径是否为自路径的前半部分,如果不是说明不是子路径,可能存在slip注入,此方法会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/ File srcFile = FileUtil.checkSlip(new File("C:\\Users\\Administrator\\Desktop\\xuzhu"),new File("contentEqualsIgnoreEOLTest1.txt")); //会报错IllegalArgumentException: New file is outside of the parent dir: contentEqualsIgnoreEOLTest1.txt Assert.assertEquals(Boolean.TRUE,srcFile.exists());
返回值:
{@link RandomAccessFile}
参考案例:
RandomAccessFile randomAccessFile = FileUtil.createRandomAccessFile(new File("C:\\Users\\Administrator\\Desktop\\xuzhu\\toCopyTest1.txt"), FileMode.r); Assert.assertNotNull(randomAccessFile);
public class IoUtilLineHandler implements LineHandler { @Override public void handle(String line) { System.out.println("handle:"+line); } } //------------------------ //实现类似Linux下"tail -f"命令功能 但监听启动时,toCopyTest1.txt文件有新增内容时,就会触发自定义的IoUtilLineHandler FileUtil.tail(FileUtil.file("C:\\Users\\Administrator\\Desktop\\xuzhu\\toCopyTest1.txt"), new IoUtilLineHandler());