package cn.baiweigang.qtaf.toolkit.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; /** * 对文件的底层操作,包括读、写,文件的及目录的创建、删除 * @author @<a href='http://weibo.com/bwgang'>bwgang</a> (bwgang@163.com)<br/> * */ public class FileUtil { private static LogUtil log=LogUtil.getLogger(FileUtil.class);//日志记录 private static List<String>filelist=new ArrayList<>(); //文件的读写 /** * 从文件中以字节流方式读取并返回 * @param pathName * @return FileInputStream */ public static FileInputStream readToFileInputStream(String pathName) { try { return new FileInputStream(pathName); } catch (FileNotFoundException e) { log.error("字节流方式读取文件失败:"+pathName); log.error(e.getMessage()); return null; } } /** * 读取字符流,指定编码 * @param patnName 文件位置,相对或绝对路径 * @param enCoding 读取时使用的编码 * @return InputStreamReader */ public static InputStreamReader readToInputStreamReader(String patnName,String enCoding) { try { return new InputStreamReader(readToFileInputStream(patnName), enCoding); } catch (Exception e) { log.error("读取文件失败:"+patnName); log.error(e.getMessage()); return null; } } /** * 读取字符流,指定编码 * @param pathName * @param enCoding * @return BufferedReader */ public static BufferedReader readToBufferedReader(String pathName,String enCoding) { try { return new BufferedReader(readToInputStreamReader((pathName), enCoding)); } catch (Exception e) { log.error("读取文件失败:"+pathName); log.error(e.getMessage()); return null; } } /** * 读取字符流,指定编码 * @param pathName * @param enCoding * @return String */ public static String readToString(String pathName,String enCoding) { BufferedReader buff=readToBufferedReader(pathName,enCoding); String line=""; StringBuilder str=new StringBuilder(); try { while ((line = buff.readLine()) != null) { str.append(line).append("\r\n"); } } catch (Exception e) { log.error(e.getMessage()); str.append(""); } return String.valueOf(str); } /** * 读取字符流,指定编码 * @param input * @param enCoding * @return String */ public static String readInputStreamToString(InputStream input,String enCoding) { BufferedReader reader ; StringBuilder sb = new StringBuilder(); String line = null; try { reader = new BufferedReader(new InputStreamReader(input,enCoding)); while ((line = reader.readLine()) != null) { sb.append(line + "\r\n"); } } catch (IOException e) { log.error(e.getMessage()); } finally { try { input.close(); } catch (IOException e) { log.error(e.getMessage()); } } return sb.toString(); } /** * 读取字符流,指定编码,按每行数据返回List * @param pathName * @param enCoding * @return List<String> */ public static List<String> readLineToList(String pathName,String enCoding) { BufferedReader br=null; String line=""; List<String>lines=new ArrayList<>(); br=readToBufferedReader(pathName, enCoding); if (null==br) return null; try { while((line=br.readLine())!=null){ lines.add(line.trim()); } br.close(); } catch (Exception e) { log.error("按行读取文件失败:"+pathName); log.error(e.getMessage()); } return lines; } /** * 创建到文件的输出流 * @param pathName * @return FileOutputStream */ public static FileOutputStream getFileOutStream(String pathName) { //先创建一空白文件 try { createFile(pathName); return new FileOutputStream(pathName); } catch (FileNotFoundException e) { log.error("创建输出到文件失败:"+pathName); log.error(e.getMessage()); return null; } } /** * 按字节写文件 * @param byteStream * @param pathName * @return boolean */ public static boolean writeByteArray(byte[] byteStream,String pathName) { boolean flag=false; try { //先创建一空白文件 FileOutputStream outStream = getFileOutStream(pathName); outStream.write(byteStream); outStream.flush(); outStream.close(); flag=true; } catch (IOException e) { log.error("写入文件失败"+pathName); log.error(e.getMessage()); flag=false; } return flag; } /** * 把字节流写入文件 * @param inStream * @param pathName * @return boolean */ public static boolean writeStream(InputStream inStream,String pathName) { byte[] temp; try { temp=new byte[inStream.available()]; inStream.read(temp); return writeByteArray(temp,pathName); } catch (Exception e) { log.error("写入文件失败1"+pathName); log.error(e.getMessage()); return false; } } /** * 把字符串按指定编码写入文件 * @param str * @param pathName * @param enCoding * @return boolean */ public static boolean writeString(String str,String pathName,String enCoding) { byte[] b; try { b=str.getBytes(enCoding); } catch (UnsupportedEncodingException e) { log.error("字符串按编码 "+enCoding+"转换字节错误"); log.error(e.getMessage()); return false; } return writeByteArray(b,pathName); } /** * 把List中的字符串按行写入文件 * @param strList * @param pathName * @param enCoding * @return boolean */ public static boolean writeString(List<String> strList,String pathName,String enCoding) { if (null==strList ) { log.error("待写入文件"+pathName+"的字符列表为null"); return false; } StringBuffer tmp=new StringBuffer(); for (int i = 0; i < strList.size(); i++) { tmp.append(strList.get(i)+"\r\n"); } return writeString(tmp.toString(), pathName, enCoding); } //文件的删除、创建、改名等操作 /** * 说明:删除指定的文件 * * @param file 文件的完整绝对路径或者相对路径 * @return boolean 删除成功返回true,删除失败、指定路径不存在返回false */ public static boolean delFile(File file) { if (file.isFile() == true) { return file.delete(); }else{ log.error("文件:"+file+" 不存在,或者不是文件类型"); } return false; } /** * 说明:删除指定的文件 * * @param pathName 文件的完整绝对路径或者相对路径 * @return boolean 删除成功返回true,删除失败、指定路径不存在返回false */ public static boolean delFile(String pathName) { File path = new File(pathName); return delFile(path); } /** * 说明:/删除指定文件夹下所有文件 * * @param folderPath 文件夹完整绝对路径或者相对路径 * @return boolean 删除成功返回true,删除失败、指定路径不存在返回false */ public static boolean delAllFile(String folderPath) { File path = new File(folderPath); if (!path.exists()) { // log.error("删除指定的文件夹:"+folderPath+"不存在"); return false; } if (!path.isDirectory()) { // log.error("删除指定的:"+folderPath+"不是个文件夹"); return false; } String[] tempList = path.list(); File temp = null; for (int i = 0; i < tempList.length; i++) { if ((path.toString()).endsWith(File.separator)) { temp = new File(path + tempList[i]); } else { temp = new File(path + File.separator + tempList[i]); } if (temp.isFile()) { delFile(temp); } if (temp.isDirectory()) { delAllFile(path + File.separator + tempList[i]);// 先删除文件夹里面的文件 delFolder(path + File.separator + tempList[i]);// 再删除空文件夹 } } return true; } /** * 说明:删除文件夹 * * @param folderPath 文件夹完整绝对路径或者相对路径 */ public static void delFolder(String folderPath) { try { delAllFile(folderPath); // 删除完里面所有内容 String filePath = folderPath; filePath = filePath.toString(); File myFilePath = new File(filePath); myFilePath.delete(); // 删除空文件夹 } catch (Exception e) { log.error("删除文件夹:"+folderPath+"出错"); log.error(e.getMessage()); } } /** * 创建目录 * @param folderPath * @return boolean 创建成功或者已存在返回true,不存在且创建失败返回false */ public static boolean createDictory(String folderPath){ if (null==folderPath) return false; File path=new File(folderPath); if(path.exists()){ return true; }else{ if (new File(folderPath).mkdirs()) { return true; } if(!path.exists()){ log.error("创建文件夹:"+folderPath+"失败"); return false; } } return true;//永远不会执行到这里,不写这句就报语法错误 } /** * 创建指定的文件,空白文件,如果上层目录不存在则会创建 * @param pathName * @return boolean */ public static boolean createFile(String pathName){ File pathNameFile=new File(pathName); if(!pathNameFile.exists()){ StringBuilder dictoryPath=new StringBuilder(pathName); dictoryPath.delete(getFileNameIndexFromPath(pathName), pathName.length()); if ( !createDictory(dictoryPath.toString()) )return false; try { pathNameFile.createNewFile(); return true; } catch (IOException e) { log.error("创建文件:"+pathName+"失败"); log.error(e.getMessage()); return false; } } return true; } /** * 判断文件或文件夹是否存在 * @param path * @return boolean 存在返回true */ public static boolean isExist(String path){ return new File(path).exists(); } /** * 返回文件扩展名 * @param fileName * @return String */ public static String getExtensionName(String fileName) { if ((fileName != null) && (fileName.length() > 0)) { int dot = fileName.lastIndexOf('.'); if ((dot >-1) && (dot < (fileName.length() - 1))) { return fileName.substring(dot + 1).toLowerCase(); } } return ""; } /** * 返回指定文件夹下所有文件路径名 * @param folderPath * @return List<String> */ public static List<String> getFilesFromFolder(String folderPath) { FileUtil myfile=new FileUtil(); return myfile.getFilesOfFolder(folderPath); } /** * 返回文件绝对路径内的上层目录 * @param absolutePath * @return String */ public static String getParentPath(String absolutePath) { if (!isExist(absolutePath)) { log.info("文件不存在:"+absolutePath); return null; } File file=new File(absolutePath); return file.getParent(); } /** * 返回文件绝对路径内的文件名 * @param absolutePath * @return String */ public static String getFileName(String absolutePath) { if (!isExist(absolutePath)) { log.info("文件不存在:"+absolutePath); return null; } File file=new File(absolutePath); return file.getName(); } /** * 返回文件夹下指定扩展名的文件列表 * @param folderPath * @param extensionName * @return List<String> */ public static List<String> getFilesFromFolder(String folderPath,String extensionName) { List<String>files=getFilesFromFolder(folderPath); List<String> tmpList=new ArrayList<>(); if (null==files) return tmpList; if (null==extensionName || extensionName.length()<1) return tmpList; for (String filename : files) { String exname=getExtensionName(filename); if (exname.indexOf(extensionName.toLowerCase())>-1) tmpList.add(filename); } return tmpList; } /** * 关闭stream,并且不抛出异常 * @param stream 待关闭的输入流 */ public static void closeStreamIgnoreExpection(InputStream stream) { try{ if(stream!=null){ stream.close(); } }catch (Exception e) { // do nothing here } } /** * 重命名文件,输入参数为完全路径名 * @param oldPathName * @param newPathName * @return boolean */ public static boolean renameFile(String oldPathName, String newPathName) { if (StringUtil.IsNullOrEmpty(oldPathName) || StringUtil.IsNullOrEmpty(newPathName))return false; if (oldPathName.equals(newPathName))return false; // 新的文件名和以前文件名不同时,才有必要进行重命名 File oldfile = new File(oldPathName); File newfile = new File(newPathName); if (newfile.exists()){// 若在该目录下已经有一个文件和新文件名相同,则不允许重命名 log.error(newPathName + "已经存在!"); return false; }else { oldfile.renameTo(newfile); return true; } } /** * 拷贝单个文件 源和目的文件都为完全路径名 * @param srcPathName * @param distPathName * @return boolean */ public static boolean copyFile(String srcPathName,String distPathName) { if (StringUtil.IsNullOrEmpty(srcPathName) || StringUtil.IsNullOrEmpty(srcPathName)) return false; if (distPathName.equals(srcPathName)) return false; return writeStream(readToFileInputStream(srcPathName), distPathName); } /** * 拷贝文件夹 * @param srcFolderPath * @param distFolderPath * @return boolean */ public static boolean copyFolder(String srcFolderPath,String distFolderPath) { if (StringUtil.IsNullOrEmpty(srcFolderPath) || StringUtil.IsNullOrEmpty(distFolderPath)) return false; if (srcFolderPath.toLowerCase().equals(distFolderPath)) return false; // 新建目标目录 createDictory(distFolderPath); // 获取源文件夹当前下的文件或目录 File[] file = (new File(srcFolderPath)).listFiles(); for (int i = 0; i < file.length; i++) { if (file[i].isFile()) { // 源文件 String sourceFile = file[i].getAbsolutePath(); // 目标文件 String targetFile =new File(distFolderPath).getAbsolutePath() +"/"+file[i].getName(); copyFile(sourceFile,targetFile); } if (file[i].isDirectory()) { // 准备复制的源文件夹 String dir1 = srcFolderPath + "/" + file[i].getName(); // 准备复制的目标文件夹 String dir2 = distFolderPath + "/" + file[i].getName(); copyFolder(dir1, dir2); } } return true; } /** * 从文件完全路径中,获取最后一个"/"或"\"的位置 * @param filePathName * @return int */ public static int getFileNameIndexFromPath(String filePathName){ if (filePathName.toLowerCase().lastIndexOf("/")>-1){ return filePathName.toLowerCase().lastIndexOf("/"); }else{ return filePathName.toLowerCase().lastIndexOf("\\"); } } /** * 返回目录下所有文件列表 * @param folderPath * @return List<String> */ private List<String> getFilesOfFolder(String folderPath) { File dir = new File(folderPath); File[] files = dir.listFiles(); if (files == null) { // log.info("此目录下未取得任何文件:"+folderPath); return null; } for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { getFilesOfFolder(files[i].getAbsolutePath()); } else { filelist.add(files[i].getAbsolutePath()); } } return filelist; } }