FileOperationUtils.java package com.xnl.utils;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileFilter;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io
package com.xnl.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; /** * 文件操作工具类: * 文件/目录的创建、删除、移动、复制、zip压缩与解压 * 文件操作过程中要注意是否有操作权限的问题,以免报错。 * commons-io-2.5.jar * ant-1.6.5.jar * @date 2017年3月1日 * @author xnl */ public class FileOperations { /*使用GBK编码避免压缩中文文件名乱码*/ private static final String CHINESE_CHARSET = "GBK"; /*文件读取缓冲区大小*/ private static final int CACHE_SIZE = 1024 * 50; /** * 压缩文件或文件夹为zip格式文件 * @param sourceFile 文件或文件夹 * @param zipFilePath 压缩文件输出路径(以.zip结尾) * @throws Exception */ public static void zip(String sourceFile, String zipFilePath) throws Exception { File sourcefile = new File(sourceFile); if (!sourcefile.exists()) { throw new Exception("指定的文件不存在!"); } File zipFile = new File(zipFilePath); if (!zipFile.getParentFile().exists()) { // 如果目标文件的父目录不存在,则创建父目录 new File(zipFile.getParentFile().getPath()).mkdirs(); } OutputStream out = new FileOutputStream(zipFilePath); BufferedOutputStream bos = new BufferedOutputStream(out); ZipOutputStream zos = new ZipOutputStream(bos); zos.setEncoding(CHINESE_CHARSET);// 解决中文文件名乱码问题 String basePath = null; if (sourcefile.isDirectory()) { basePath = sourcefile.getPath(); } else { basePath = sourcefile.getParent(); } zipFile(sourcefile, basePath, zos); zos.closeEntry(); zos.close(); bos.close(); out.close(); } /** * 递归压缩文件 * @param parentFile * @param basePath * @param zos * @throws Exception */ private static void zipFile(File parentFile, String basePath, ZipOutputStream zos) throws Exception { File[] files = new File[0]; if (parentFile.isDirectory()) { files = parentFile.listFiles(); } else { files = new File[1]; files[0] = parentFile; } String pathName; InputStream is; BufferedInputStream bis; byte[] cache = new byte[CACHE_SIZE]; for (File file : files) { // TODO 判断文件是否正在读写中,如果是,则不压缩该文件。 if (!file.renameTo(file)) { continue; } if (file.isDirectory()) { pathName = file.getPath().substring(basePath.length() + 1) + File.separator; zos.putNextEntry(new ZipEntry(pathName)); zipFile(file, basePath, zos); } else { pathName = file.getPath().substring(basePath.length() + 1); is = new FileInputStream(file); bis = new BufferedInputStream(is); zos.putNextEntry(new ZipEntry(pathName)); int nRead = 0; while ((nRead = bis.read(cache, 0, CACHE_SIZE)) != -1) { zos.write(cache, 0, nRead); } bis.close(); is.close(); } } } /** * 功能:压缩多个文件成一个zip文件 * @param sourceFile:源文件列表 * @param targetZipFile:压缩后的文件 * @throws Exception */ public static void zipFiles(File[] sourceFiles, File targetZipFile) throws Exception { byte[] buf = new byte[CACHE_SIZE]; ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetZipFile)); zos.setEncoding(CHINESE_CHARSET);// 解决中文文件名乱码问题 FileInputStream fis = null; for (int i = 0; i < sourceFiles.length; i++) { fis = new FileInputStream(sourceFiles[i]); zos.putNextEntry(new ZipEntry(sourceFiles[i].getName())); int len; while ((len = fis.read(buf)) > 0) { zos.write(buf, 0, len); } if (zos != null) { zos.closeEntry(); } if (fis != null) { fis.close(); } } if (zos != null) { zos.close(); } } /** * 解压指定的zip压缩包到目标目录 * 对应的是ant-1.6.5.jar * @param sourceFile 指定的zip压缩包文件 * @param destDir 目标目录 * @throws Exception */ public static void unzip(String sourceFile, String destDir) throws Exception { Project p = new Project(); Expand expand = new Expand(); expand.setProject(p); expand.setSrc(new File(sourceFile)); expand.setOverwrite(false); expand.setDest(new File(destDir)); expand.setEncoding(CHINESE_CHARSET); expand.execute(); } /** * copy普通文件到目标文件夹下 * @param sourceFile 源文件路径 * @param targetDir 目标文件夹路径 * @throws Exception */ public static void copyFileToDir(String sourceFile, String targetDir) throws Exception { File source = new File(sourceFile); File target = new File(targetDir); FileUtils.copyFileToDirectory(source, target); } /** * copy普通文件到目标文件,可实现文件同目录改名 * @param sourceFile 普通文件 * @param targetFile 目标文件 * @throws Exception */ public static void copyFileToFile(String sourceFile, String targetFile) throws Exception { File source = new File(sourceFile); File target = new File(targetFile); FileUtils.copyFile(source, target); } /** * copy指定文件夹到目标文件夹 * @param sourceDir 指定原文件夹 * @param targetDir 目标文件夹 * @throws Exception */ public static void copyDirToDir(String sourceDir, String targetDir) throws Exception { File source = new File(sourceDir); File target = new File(targetDir); FileUtils.copyDirectoryToDirectory(source, target); } /** * 删除指定的文件夹(递归删除多级目录) * 注意:不论文件夹是否为空都可以删除 * @param sourceDir 指定的文件夹路径 * @throws Exception */ public static void deleteDir(String sourceDir) throws Exception { File directory = new File(sourceDir); FileUtils.deleteDirectory(directory); } /** * 删除文件或文件夹, * 注意:不论文件夹是否为空都可以删除,请慎用 * @param sourceFilePath 指定的文件\文件夹路径 */ public static void deleteFile(String sourceFilePath) { File source = new File(sourceFilePath); FileUtils.deleteQuietly(source); } /** * 指定文件移动到目标文件,可以实现指定文件的同目录下改名,同时会删除原文件 * @param sourceFile 指定文件路径 * @param targetFile 目标文件路径 * @throws Exception */ public static void moveFileToFile(String sourceFile, String targetFile) throws Exception { File source = new File(sourceFile); File target = new File(targetFile); FileUtils.moveFile(source, target); } /** * 指定文件移动到目标目录下,同时会删除原文件 * @param sourceFile 指定文件 * @param targetDir 目标目录 * @throws Exception */ public static void moveFileToDir(String sourceFile, String targetDir) throws Exception { File source = new File(sourceFile); File target = new File(targetDir); FileUtils.moveToDirectory(source, target, true); } /** * 指定目录移动到目标目录,同时会删除原目录 * @param sourceDir 指定源目录 * @param targetDir 目标目录 * @throws Exception */ public static void moveDirToDir(String sourceDir, String targetDir) throws Exception { File source = new File(sourceDir); File target = new File(targetDir); FileUtils.moveDirectoryToDirectory(source, target, true); } /** * 创建单个普通文件(不能是目录) * @param descFileName 文件名,包含路径 * @return 如果文件创建成功,则返回true,否则返回false * @throws Exception */ public static boolean createFile(String descFileName) throws Exception { File file = new File(descFileName); if (file.exists()) { // 如果文件已经存在,则创建失败 return false; } if (descFileName.endsWith(File.separator)) { // 如果文件路径以'/'结尾,则是目录,不能创建目录 return false; } if (!file.getParentFile().exists()) { // 如果文件的父目录不存在,则需要创建 // 如果文件所在的目录不存在,则创建目录 if (!file.getParentFile().mkdirs()) { // 如果父目录创建失败,则文件创建也失败 return false; } } if (file.createNewFile()) { // 文件创建成功 return true; } else { // 文件创建失败 return false; } } /** * 创建目录 * @param descDirName 目录名,包含路径 * @return 如果目录创建成功,则返回true,否则返回false */ public static boolean createDirectory(String descDirName) { String descDirNames = descDirName; if (!descDirNames.endsWith(File.separator)) { descDirNames = descDirNames + File.separator; } File descDir = new File(descDirNames); if (descDir.exists()) { // 目录已经存在,则创建失败 return false; } if (descDir.mkdirs()) { // 创建成功 return true; } else { // 创建失败 return false; } } /** * 压缩指定文件夹下符合匹配规则的文件到目标目录下 * @param regex 匹配规则 * @param sourceDir 源文件夹 * @param targetZipFile 目标zip文件的路径及名称 * @param isEnd 是否以regex匹配规则结尾,为true则表示按照扩展名过滤,false则表示按照文件名(除扩展名外)过滤 * @throws Exception */ public static void zip(String regex, String sourceDir, String targetZipFile, boolean isEnd) throws Exception { File sourceDirFile = new File(sourceDir); File targetZip = new File(targetZipFile); if (!targetZip.getParentFile().exists()) { new File(targetZip.getParent()).mkdirs(); } File[] files = null; if (!isEmpty(regex) && isEnd) { // 源文件夹下符合过滤条件的文件,不包含子文件夹中的文件在内 files = sourceDirFile.listFiles(new ExtensionFilter(regex)); } else if (!isEmpty(regex) && !isEnd) { // 源文件夹符合过滤条件的所有文件及文件夹的路径及名称,不包含子文件夹中的文件或文件夹在内 files = sourceDirFile.listFiles(new NameFilter(regex)); } else { // 源文件夹下的所有的文件/文件夹的路径及名称,不包含子文件夹内的文件/文件夹 files = sourceDirFile.listFiles(); } System.out.println(Arrays.toString(files)); if (files != null && files.length > 0) { zipFiles(files, targetZip); } else { throw new Exception("不存在符合匹配规则的文件!"); } } private static boolean isEmpty(String str) { if (str == null || "".equals(str)) { return true; } return false; } } /**文件名过滤器,只匹配符合规则的文件,不包括文件夹*/ class NameFilter implements FilenameFilter { /*匹配规则*/ private String regex; public NameFilter(String regex) { this.regex = regex; } @Override public boolean accept(File dir, String name) { File f = new File(dir.getPath() + File.separator + name); if (f.isDirectory()) { return false; } if (name.contains(".")) { name = name.substring(0, name.lastIndexOf(".")); // 将文件名的扩展名去掉 } if (name.indexOf(regex) > -1) { return true; } return false; } } /**扩展名过滤器,只匹配符合规则的文件,不包括文件夹*/ class ExtensionFilter implements FileFilter { /*匹配规则*/ private String regex; public ExtensionFilter(String regex) { this.regex = regex; } @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { return false; } String filename = pathname.getName(); boolean isMatched = filename.endsWith(regex); if (pathname.isFile() && isMatched) { return true; } return false; } }