package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.util.StringUtil;
import com.aliyuncs.utils.IOUtils;
import org.springframework.util.FileCopyUtils;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * Created by AKmm at 2011-6-10 10:13:05
 * 文件操作方法
 */
@SuppressWarnings({"UnusedDeclaration", "ResultOfMethodCallIgnored"})
public class UtilFile {
    //使用了"/"，暂未使用File.separator，因为在Windows下获取的"\"，以及通过Url.getPath获取的路径中的"/"，拼接路径会导致错误发生。暂时全部使用"/";
    public static final String FSChar = "/";
    //    public static final String FSChar = File.separator;

    /**
     * create new file
     * modify by huchb in 2012.08.14
     *
     * @param fileName 文件名，带路径
     * @return true is success
     */
    public static boolean CreateFile(String fileName) {
        File f = new File(fileName);
        f.getParentFile().mkdirs();
        try {
            return f.createNewFile();
        } catch (IOException e) {
            UtilLogger.error("创建文件出错", e);
            return false;
        }
    }

    /**
     * UTF-8编码写入
     *
     * @param text     文件内容
     * @param fileName 文件名称
     */
    public static void appendTextToFileEncode(String text, String fileName, boolean append) {
        try {
            OutputStreamWriter oStreamWriter = new OutputStreamWriter(new FileOutputStream(fileName, append), StandardCharsets.UTF_8);
            oStreamWriter.append(text);
            oStreamWriter.flush();
            oStreamWriter.close();
        } catch (IOException e) {
            UtilLogger.error(e.getMessage(), e);
        }
    }

    /**
     * 删除文件
     * modify by huchb in 2012.08.14
     *
     * @param dirName   源文件或目录
     * @param isRecurse 如果是目录,是否删除其下的子目录 (是否迭代)
     * @return true-成功,false-失败
     */
    public static boolean deleteFile(String dirName, boolean isRecurse) {
        File f = new File(dirName);
        if (f.isFile()) {
            return f.delete();
        }
        boolean blret = true;
        try {
            //取出目录下的文件数量；
            File[] childsf = f.listFiles();
            if (childsf != null) {
                int filenumber = childsf.length;
                for (File cf : childsf) {
                    if (cf.isFile()) {
                        blret = cf.delete();
                    } else if (isRecurse) {
                        blret = deleteFile(cf.getAbsolutePath(), true);
                    }
                    if (!blret) {
                        break;
                    }  //没删除成功，跳出内循环，并退出函数，返回删除不成功；
                }
                //删除空目录
                blret = new File(dirName).delete();
            }
        } catch (Exception e) {
            UtilLogger.error(e.getMessage(), e);
            blret = false;
        }
        return blret;
    }

    //删除文件或目录
    public static boolean delFile(String path) {
        File f = new File(path);
        return !f.exists() || delFile(f);
    }

    public static boolean delFile(File f) {
        if (f.isFile())
            return f.delete();
        return delDir(f);
    }

    /**
     * 将data写到fn中 fn为绝对路径
     *
     * @param fn   保存文件名
     * @param data 数据
     * @return int
     * @roseuid 3C297D4D0102
     */
    public static int saveFile(String fn, byte[] data) {
        try {
            FileOutputStream fos = new FileOutputStream(fn);
            fos.write(data, 0, data.length);
            fos.flush();
            fos.close();
            return 0;
        } catch (IOException e) {
            UtilLogger.error(e.getMessage(), e);
            return 100;
        }
    }

    /**
     * @param text     文件内容
     * @param fileName 文件名称
     * @param append   是否追加的文件的尾部
     *                 如果append=true 则将内容追加的文件的尾部
     *                 否则，从头开始
     */
    public static void writeTextToFile(String text, String fileName, boolean append) {
        try {
            Writer write = new FileWriter(fileName, append);
            write.write(text);
            write.flush();
            write.close();
        } catch (IOException e) {
            UtilLogger.error(e.getMessage(), e);
        }
    }

    /**
     * 本方法主要用于将一个文件拷贝到另一个文件件
     *
     * @param from 源文件
     * @param to   目的文件
     * @return 返回字节数,-1:读文件错误，－2：文件未找到，-3： IO错误
     */
    public static int copyFile(String from, String to) {
        int n = 0;
        try {
            // copy 会自动关闭input,output.
            FileCopyUtils.copy(new File(from), new File(to));   //调用org.springframework.cf;中的类方法
            /*System.out.println("now copy file from " + from + " to " + to);
            is = new FileInputStream(from);
            byte[] bts = new byte[is.available()];
            int len = bts.length;
            System.out.println("now open file");
            os = new FileOutputStream(to);
            System.out.println("now open file success");
            int len1 = is.read(bts, 0, bts.length);
            System.out.println("now start write file");
            os.write(bts, 0, bts.length);
            bts = null;
            n = len == len1 ? len : -1;*/
        } catch (FileNotFoundException fe) {
            UtilLogger.error(fe.getMessage(), fe);
            n = -2;
        } catch (IOException ie) {
            UtilLogger.error(ie.getMessage(), ie);
            n = -3;
        } catch (Exception e) {
            UtilLogger.error("", e);
            n = -1;
        }
        return n;
    }

    /**
     * 复制文件
     *
     * @param oldPath 源文件
     * @param newPath 目标文件名
     * @return 成功/失败
     */
    public static boolean copy(String oldPath, String newPath) {
        return copy(new File(oldPath), newPath, false);
    }

    /**
     * 复制/移动文件（夹）
     *
     * @param oldPath  旧文件
     * @param newPath  新文件
     * @param isDelOld 是否删除旧文件，删除相当于移动；
     * @return 是否删除成功
     */
    public static boolean copy(String oldPath, String newPath, boolean isDelOld) {
        File f = new File(oldPath);
        return copy(f, newPath, isDelOld);
    }

    /**
     * 复制/移动文件（夹）
     *
     * @param oldfile  源文件
     * @param newPath  新文件名
     * @param isDelOld 是否删除旧文件名（移动方式）
     * @return 成功/成败
     */
    public static boolean copy(File oldfile, String newPath, boolean isDelOld) {
        try {
            if (!oldfile.exists()) return true;
            if (oldfile.isFile()) return copyFile(oldfile, newPath, isDelOld);

            return copyDir(oldfile, newPath, isDelOld);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean copyFile(File oldfile, String newPath, boolean isDelOld) {
        if (!oldfile.exists()) return true;
        int byteread;
        try {
            File f = new File(newPath);
            f.getParentFile().mkdirs();
            try (FileOutputStream fs = new FileOutputStream(newPath); InputStream inStream = new FileInputStream(oldfile)) {
                byte[] buffer = new byte[1444];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
            }
            if (isDelOld) oldfile.delete();
            return true;
        } catch (Exception e) {
            UtilLogger.error("复制文件失败。", e);
            return false;
        }
    }

    public static void copyFileToIcDir(String srcFileDir, String destFileDir) {
        String[] srcFiles = getFileNames(srcFileDir);
        try {
            if (srcFiles != null && srcFiles.length > 0) {
                for (String srcFile : srcFiles) {
                    if (!srcFile.endsWith(".zip")) {
                        copyFile(srcFileDir + "\\" + srcFile, destFileDir + "\\" + srcFile);
                    } //if
                } //for
            }
        } catch (Exception e) {
            e.printStackTrace();
            UtilLogger.error("拷贝文件出错！", e);
        }
    }

    public static boolean copyDir(File file, String newPath, boolean isDelOld) {
        if (newPath.endsWith(FSChar)) newPath += FSChar;
        makeDir(newPath);
        File[] files = file.listFiles();
        if (files != null && files.length > 0) {
            for (File temp : files) {
                if (temp.isFile()) {
                    if (!copyFile(temp, newPath + FSChar + getFullName(temp.getPath()), isDelOld)) return false;
                } else if (!copyDir(temp, newPath + FSChar + getFullName(temp.getPath()), isDelOld)) return false;
            }
        }
        return !isDelOld || delFile(file);
    }


    /**
     * 将输入流拷贝到输出流
     *
     * @param in  输入流
     * @param out 输出流
     * @throws IOException
     */
    public static int copyStream(InputStream in, OutputStream out) throws IOException {
        // 改为一次读取4096个字节.
        byte[] buf = new byte[4096];
        int byteCount = 0;
        int bytesRead;
        while ((bytesRead = in.read(buf, 0, buf.length)) != -1) {
            out.write(buf, 0, bytesRead);
            byteCount += bytesRead;
        }
        out.flush();
        return byteCount;
    }

    /**
     * 查找压缩文件
     *
     * @param bFlag      搜索位置标志 true：从左到右 false：从右到左
     * @param sSearchStr 要搜索的字符串
     *                   return 文件名
     */
    public static String searchFile(String sSearchStr, boolean bFlag, String sFilePath) {
        try {
            String sFileName = "";
            String[] fls = getFileNames(sFilePath);
            if (fls != null && fls.length > 0) {
                for (String fl : fls) {
                    if (bFlag) {
                        if (fl.toLowerCase().contains(sSearchStr.toLowerCase())) {
                            sFileName = fl;
                            break;
                        }
                    } else {
                        if (fl.toLowerCase().lastIndexOf(sSearchStr.toLowerCase()) >= 0) {
                            sFileName = fl;
                            break;
                        }
                    }
                }
            }
            return sFileName;
        } catch (Exception e) {
            return "";
        }
    }


    /**
     * 查找所有的文件     *
     *
     * @param sSearchStr 要搜索的字符串
     *                   return 文件名list
     */
    public static List<String> searchFiles(String sSearchStr, String sFilePath) {
        List<String> list = new ArrayList<>();
        try {
            String sFileName = "";
            String[] fls = getFileNames(sFilePath);
            if (fls != null && fls.length > 0) {
                for (String fl : fls) {
                    if (fl.toLowerCase().contains(sSearchStr.toLowerCase())) {
                        sFileName = fl;
                        list.add(sFileName);
                    }
                }
            }
            return list;
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 创建文件路径
     *
     * @param baseDir 该目录所在的父目录
     * @param dirName 目录名
     * @return true-成功;False-不成功
     */
    public static boolean mkDir(String baseDir, String dirName) {
        return mkDir(baseDir + FSChar + dirName);
    }

    /**
     * 创建文件路径
     *
     * @param destDir 目录名
     * @return true-成功;False-不成功
     */
    public static boolean mkDir(String destDir) {
        boolean blRet = false;
        int idx = destDir.lastIndexOf(FSChar);
        if (idx == -1)
            throw new IllegalArgumentException("输入参数不是一个合法的路径");
        return new File(destDir).mkdirs();
    }

    //创建目录
    public static boolean makeDir(String path) {
        File f = new File(path);
        return f.exists() || f.mkdirs();
    }

    /**
     * 删除目录
     *
     * @param file 文件对象；
     */
    public static boolean delDir(File file) {
        File[] files = file.listFiles();
        if (files != null) {
            for (File temp : files) {
                if (temp.isFile()) {
                    if (!temp.delete()) return false;
                } else if (!delDir(temp)) return false;
            }
            return file.delete();
        }
        return true;
    }

    public static boolean delAllFile(String path) {
        File file = new File(path);
        File[] files = file.listFiles();
        if (files != null) {
            for (File temp : files) {
                if (temp.isFile()) {
                    if (!temp.delete()) return false;
                } else if (!delDir(temp)) return false;
            }
        }
        return true;
    }

    public static String refineFilePath(String fn) {
        String s = fn.replace('\\', File.separatorChar);
        s = s.replace('/', File.separatorChar);
        int i = s.indexOf("//");
        if (i > 0) s = s.substring(0, i) + s.substring(i + 1);
        i = s.indexOf("\\\\");
        if (i > 0) s = s.substring(0, i) + s.substring(i + 1);
        return s;

    }

    /**
     * 从fn中读取所有内容
     *
     * @param fn 源文件名
     * @return byte[]
     * @roseuid 3C297D710384
     */
    public static byte[] loadFromFile(String fn) {
        try {
            FileInputStream fis = new FileInputStream(fn);
            byte[] data = new byte[fis.available()];
            fis.read(data, 0, data.length);
            fis.close();
            return data;
        } catch (IOException e) {
            UtilLogger.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从fn中读取所有内容
     *
     * @param fn 源文件名
     * @return byte[]
     * @roseuid 3C297D710384
     */
    public static byte[] loadFromFile(String fn, int size) {
        try {
            FileInputStream fis = new FileInputStream(fn);
            int avail = fis.available();
            byte[] data;
            if (avail > size) {
                data = new byte[size];
            } else {
                data = new byte[avail];
            }
            fis.read(data, 0, data.length);
            fis.close();
            return data;
        } catch (IOException e) {
            UtilLogger.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从fn中读取所有内容
     *
     * @param fn 源文件名
     * @return byte[]
     * @roseuid 3C297D710384
     */
    public static byte[] loadFromFile(File fn) {
        try {
            FileInputStream fis = new FileInputStream(fn);
            byte[] data = new byte[fis.available()];
            fis.read(data, 0, data.length);
            fis.close();
            return data;
        } catch (IOException e) {
            UtilLogger.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据文件路径取得该文件路径下的所有文件(含子目录)：
     *
     * @param fp filePath
     * @return 存放文件的数组
     */
    public static File[] getFiles(String fp) {
        if (fp == null || fp.length() <= 2) {
            UtilLogger.debug("文件路径错误");
            return null;
        }
        File f = new File(fp);
        if (f.isFile()) {
            UtilLogger.debug("文件路径非文件夹");
            return new File[]{};
        }
        return f.listFiles();
    }

    /**
     * 根据文件路径取得该文件路径下的所有文件名称：
     *
     * @param filePath 路径
     * @return 存放文件名称的数组
     */
    public static String[] getFileNames(String filePath) {
        if (filePath == null || filePath.length() <= 2) {
            return null;
        }
        File f = new File(filePath);
        if (f.isFile()) {
            return null;
        }
        return f.list();
    }

    /**
     * 根据文件路径取得该文件路径下的所有文件名称：
     *
     * @param filePath 目录名
     * @param filters  过滤文件
     * @return list<String>
     */
    public static List<String> getFileNames(String filePath, String filters) {
        List<String> list = new ArrayList<>();
        String[] files = getFileNames(filePath);
        if (files == null) {
            return list;
        }
        for (String file : files) {
            if (file.toLowerCase().endsWith(filters) || file.toUpperCase().endsWith(filters))
                list.add(file);
        }
        return list;
    }

    /**
     * filePath路径下是否存在文件fn
     *
     * @param fp 文件路径
     * @param fn 文件名称
     * @return 存放文件名称的数组
     */
    public static boolean isFileExist(String fp, String fn) {
        if (fp == null || fn == null) return false;
        String absPath;
        if (fp.endsWith("/") || fp.endsWith("\\")) {
            absPath = fp + fn;
        } else {
            absPath = fp + FSChar + fn;
        }
        return (new File(absPath)).exists();
    }

    /**
     * 文件fn是否存在
     *
     * @param fn fileName
     * @return boolean
     */
    public static boolean isFileExist(String fn) {
        return !(fn == null || fn.length() < 1) && (new File(fn)).exists();
    }

    /**
     * 获取父目录
     *
     * @param fan 全路径文件名
     * @return 父目录
     */
    public static String getParentPath(String fan) {
        try {
            String pp = fan;
            while (pp.lastIndexOf(FSChar) == (pp.length() - 1) || pp.lastIndexOf(File.separator) == (pp.length() - 1)) {
                pp = pp.substring(0, pp.length() - 2);
            }
            int idx = pp.lastIndexOf(FSChar);
            pp = pp.substring(0, idx);
            return pp;
        } catch (Exception e) {
            UtilLogger.error(e.getMessage(), e);
            return null;
        }

    }

    /**
     * 从输入流中所有内容到数组中
     *
     * @param is Description of Parameter
     * @return Description of the Returned Value
     */
    public static byte[] readToBytes(InputStream is) {
        byte[] buffer;
        int SIZE = 1024 * 1024;
        ByteArrayOutputStream bao = null;
        try {
            bao = new ByteArrayOutputStream();

            buffer = new byte[SIZE];
            BufferedInputStream in = new BufferedInputStream(is, 1024 * 1024);
            int iBytes = 0;
            while (iBytes != -1) {
                iBytes = in.read(buffer, 0, SIZE);
                if (iBytes != -1) {
                    bao.write(buffer, 0, iBytes);
                }
            }
            return bao.toByteArray();
        } catch (IOException ex) {
            UtilLogger.error(ex.getMessage(), ex);
            return null;
        } finally {
            try {
                if (bao != null) bao.close();
            } catch (Exception ignored) {
            }
        }
    }

    /**
     * 读配置文件
     * searchstr="stic";
     * srcPath=".ini"
     */
    public static String ReadINI(String searchstr, String srcPath) {
        String str;
        String temp = null;
        BufferedReader br = null;
        searchstr = searchstr.toLowerCase();
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(srcPath)));
            str = br.readLine();
            while (str != null) {
                str = str.trim();
                if (str.length() > 0 && !str.startsWith("#")) {
                    if (str.toLowerCase().contains(searchstr)) {
                        temp = str.substring(str.indexOf("=") + 1);
                        temp = temp.replace('\\', '/');
                        break;
                    }
                }
                str = br.readLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) br.close();
            } catch (Exception ignored) {
            }
        }
        return temp;
    }

    /**
     * 检查文件名是否满足Windows风格的通配符<p>
     * 如*表示任意多个字符，？表示任意一个字符<p>
     *
     * @param fileName：原文件名
     * @param filters：      通配符(*.*,a?.exe,*.zip)
     * @return true false;
     */
    public static boolean checkFileNames(String fileName, String filters) {
        fileName = getRelativeFileName(fileName);
        if (fileName == null || filters == null)
            return false;
        String[] arr_filters = filters.split(",");
        //没有通配符，表示任意字符
        if (arr_filters == null || arr_filters.length == 0) return true;
        int len = arr_filters.length;
        String filter;
        for (String arr_filter : arr_filters) {
            filter = arr_filter;
            filter = filter.trim();
            //java中,"."表示任意字符
            filter = filter.replaceAll("\\.", "\\\\.");
            filter = filter.replaceAll("\\*", "\\.\\*");
            filter = filter.replace('?', '.');
            if (fileName.matches(filter)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取文件名（绝对路径）的相对文件名
     *
     * @param fileAbsoluteName 绝对路径
     * @return string
     */
    public static String getRelativeFileName(String fileAbsoluteName) {
        if (fileAbsoluteName == null)
            return null;
        int pos1 = fileAbsoluteName.lastIndexOf("\\");
        int pos2 = fileAbsoluteName.lastIndexOf("/");
        int pos = Math.max(pos1, pos2);
        if (pos == -1)
            return fileAbsoluteName;
        return fileAbsoluteName.substring(pos + 1);
    }

    /**
     * 拷贝下文件(非深层次拷贝)
     *
     * @param srcFileDir  源
     * @param destFileDir 目标
     * @return 有效的拷贝结果；
     */
    public static boolean copyDirFileToDir(String srcFileDir, String destFileDir) {
        String[] srcFiles = getFileNames(srcFileDir);
        try {
            if (srcFiles != null && srcFiles.length > 0) {
                for (String srcFile : srcFiles) {
                    copyFile(srcFileDir + "\\" + srcFile, destFileDir + "\\" + srcFile);
                }
                return true;
            }
        } catch (Exception e) {
            UtilLogger.error("拷贝文件出错！", e);
        }
        return false;
    }

    /**
     * 重命名，通过复制的方式
     */
    public static boolean renameTo(String srcFile, String destFile) {
        return copy(new File(srcFile), destFile, true);
    }

    /**
     * 重命名，直接rename，警告，如果想跨盘move，此方法在linux下可能会失败
     *
     * @param srcFile  原名
     * @param destFile 目标名字
     * @return
     */
    public static boolean renameToEx(String srcFile, String destFile) {
        File f = new File(srcFile);
        if (!f.exists()) return false;
        File df = new File(destFile);
        return f.renameTo(df);
    }

    /**
     * 从文件全路径串中分离出有效的目录名称；
     *
     * @param filepath
     * @return 路径，以分隔符结束；
     */
    public static String getFullPath(String filepath) {
        int index = filepath.lastIndexOf(FSChar);
        if (index != -1) {
            return filepath.substring(0, index + 1);
        } else {
            return "";
        }
    }

    /**
     * 获取文件全名
     *
     * @param fileName 文件路
     * @return fullPathAndFullName
     */
    public static String getFullName(String fileName) {
        File f = new File(fileName);
        return f.getName();
    }

    /**
     * 获取文件名
     *
     * @param fullPathAndFullName 全路径文件名；
     * @return 文件名
     */
    public static String getName(String fullPathAndFullName) {
        String fullName = getFullName(fullPathAndFullName);
        int index = fullName.lastIndexOf(".");
        if (index != -1) {
            return fullName.substring(0, index);
        } else {
            return fullName;
        }
    }

    /**
     * 获取文件扩展名
     *
     * @param filepath
     * @return string
     */
    public static String getExtName(String filepath) {
        String fullName = getFullName(filepath);
        int index = fullName.lastIndexOf(".");
        if (index != -1) {
            return fullName.substring(index + 1);
        } else {
            return "";
        }
    }

    /**
     * 文件是否存在
     *
     * @param fileName
     * @return
     */
    public static boolean isFileExists(String fileName) {
        File f = new File(fileName);
        return f.exists();
    }

    //取得文件大小
    public static long getFileSize(File f) {
        if (f.exists()) {
            try {
                try (FileInputStream fis = new FileInputStream(f)) {
                    return fis.available();
                }
            } catch (IOException e) {
                return 0L;
            }
        }
        return 0;
    }

    public static long getFileSize(String path) {
        return getFileSize(new File(path));
    }

    public static void main(String[] args) throws IOException {
        //        copy("f:/temp/33/worklog_new1", "f:/temp/worklog_new", true);
        renameToEx("f:/temp/worklog_new1", "f:/temp/33/worklog_new1");
    }

    /**
     * 获取文件列表；
     *
     * @param dir       文件路径
     * @param suffix    后缀名
     * @param max_level 遍历目录深度，0表示至只获取当前目录，1 标识下级目录， -1标识所有子目录
     * @return List
     */
    public static List<String> getDirFileList(String dir, String suffix, int max_level) {
        File file = new File(dir);
        List<String> fileList = new ArrayList<>();
        getDirFileList(fileList, file, suffix, 0, max_level);
        return fileList;
    }

    /**
     * 获取文件列表；
     *
     * @param dir       目录对象；
     * @param suffix    后缀名
     * @param level     深度；
     * @param max_level 最大深度；
     * @return
     */
    public static void getDirFileList(List<String> fileList, File dir, String suffix, int level, int max_level) {
        if (max_level >= 0 && level > max_level) return;

        File[] childs = dir.listFiles();
        if (childs == null) return;

        for (File child : childs) {
            if (child.isDirectory()) {
                getDirFileList(fileList, child, suffix, level + 1, max_level);
            } else {
                //String filePath = child.getAbsolutePath();
                String filePath = child.getName();
                if (StringUtil.isEmpty(suffix)) {
                    //后缀名为null则为所有文件
                    fileList.add(filePath);
                } else {
                    int begIndex = filePath.lastIndexOf(".");//最后一个.(即后缀名前面的.)的索引
                    String tempsuffix = "";
                    //防止是文件但却没有后缀名结束的文件
                    if (begIndex != -1) {
                        tempsuffix = filePath.substring(begIndex + 1);
                    }
                    if (tempsuffix.equals(suffix)) {
                        fileList.add(filePath);
                    }
                }
            }
        }
    }

    /**
     * 获取文件列表；
     *
     * @param dir       文件路径
     * @param suffix    后缀名
     * @param max_level 遍历目录深度，0表示至只获取当前目录，1 标识下级目录， -1标识所有子目录
     * @return List
     */
    public static List<File> getFiles(String dir, String suffix, int max_level) {
        File file = new File(dir);
        List<File> fileList = new ArrayList<>();
        getFiles(fileList, file, suffix, 0, max_level);
        return fileList;
    }

    /**
     * 获取文件列表；
     *
     * @param dir       目录对象；
     * @param suffix    后缀名
     * @param level     深度；
     * @param max_level 最大深度；
     * @return 文件组合
     */
    public static void getFiles(List<File> fileList, File dir, String suffix, int level, int max_level) {
        if (max_level >= 0 && level > max_level) return;

        File[] childs = dir.listFiles();
        if (childs == null) return;

        for (File child : childs) {
            if (child.isDirectory()) {
                getFiles(fileList, child, suffix, level + 1, max_level);
            } else {
                String filePath = child.getName();
                if (StringUtil.isEmpty(suffix)) {
                    //后缀名为null则为所有文件
                    fileList.add(child);
                } else {
                    int begIndex = filePath.lastIndexOf(".");//最后一个.(即后缀名前面的.)的索引
                    String tempsuffix = "";
                    //防止是文件但却没有后缀名结束的文件
                    if (begIndex != -1) {
                        tempsuffix = filePath.substring(begIndex + 1);
                    }
                    if (tempsuffix.equals(suffix)) {
                        fileList.add(child);
                    }
                }
            }
        }
    }


    public static void zipFile(String zipFileName, File inputFile) throws Exception {
        System.out.println("压缩中...");
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
                zipFileName));
        BufferedOutputStream bo = new BufferedOutputStream(out);
        try {
            zipFile(out, inputFile, inputFile.getName(), bo);
        } finally {
            IOUtils.closeQuietly(bo);
            IOUtils.closeQuietly(out);
        }

        System.out.println("压缩完成");
    }

    private static void zipFile(ZipOutputStream out, File f, String base, BufferedOutputStream bo) throws Exception { // 方法重载
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
            if (fl.length == 0) {
                out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
//                System.out.println(base + "/");
            }
            for (int i = 0; i < fl.length; i++) {
                zipFile(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
            }
        } else {
            out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
//            System.out.println(base);
            FileInputStream in = new FileInputStream(f);
            BufferedInputStream bi = new BufferedInputStream(in);
            try {
                int b = bi.available();
                byte[] data = new byte[b];
                while ((bi.read(data, 0, b)) != -1) {
                    bo.write(data, 0, b); // 将字节流写入当前zip目录
                    bo.flush();
                }
            } finally {
                IOUtils.closeQuietly(bi);
                IOUtils.closeQuietly(in);
            }

        }
    }


    //解压缩返回解压之后的文件夹路径
    public static String unZipFile(File zipFile, String outpath) {
        String fileout = "";
        long startTime = System.currentTimeMillis();
        try {
            ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile));//输入源zip路径
            BufferedInputStream bin = new BufferedInputStream(zin);
            String Parent = outpath; //输出路径（文件夹目录）
            File Fout = null;
            ZipEntry entry;
            try {
                UtilLogger.debug("开始解压文件：" + zipFile.getName());
                while ((entry = zin.getNextEntry()) != null) {
                    String name = entry.getName();
                    Fout = new File(Parent, name);
                    if (name.split("\\/").length > 1) fileout = name.split("\\/")[0];
                    if (!Fout.exists()) {
                        (new File(Fout.getParent())).mkdirs();
                    }
                    if (entry.isDirectory()) continue;
                    UtilLogger.debug("   解压：" + name);

                    FileOutputStream out = new FileOutputStream(Fout);
                    BufferedOutputStream Bout = new BufferedOutputStream(out);
                    try {
                        int b;
                        while ((b = bin.read()) != -1) {
                            Bout.write(b);
                        }
                    } finally {
                        IOUtils.closeQuietly(Bout);
                        IOUtils.closeQuietly(out);
                    }
//                    System.out.println(Fout+"解压成功");
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(bin);
                IOUtils.closeQuietly(zin);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        UtilLogger.debug("解压完成！耗费时间： " + (endTime - startTime) + " ms");
        return outpath + "\\" + fileout;
    }

    /**
     * 读取txt文件类型
     *
     * @param fileName
     * @return
     */
    public static String readFileContent(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        StringBuffer sbf = new StringBuffer();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                sbf.append(tempStr);
            }
            reader.close();
            return sbf.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return sbf.toString();
    }

    /**
     * 解压文件到指定目录
     *
     * @param zipFile
     * @param descDir
     * @author isea533
     */
    public static void unZipFiles(File zipFile, String descDir) throws IOException {
        if (!descDir.endsWith("\\") && !descDir.endsWith("/")) descDir = descDir + "/";
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        Charset gbk = Charset.forName("GBK");
        ZipFile zip = new ZipFile(zipFile, gbk);
        UtilLogger.debug("开始解压文件：" + zipFile.getName());
        try {
            for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                InputStream in = zip.getInputStream(entry);
                try {
                    String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");

                    //判断路径是否存在,不存在则创建文件路径
                    File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
                    if (new File(outPath).isDirectory()) {
                        continue;
                    }
                    UtilLogger.debug("   解压：" + zipEntryName);
                    //输出文件路径信息
                    //            System.out.println(outPath);

                    OutputStream out = new FileOutputStream(outPath);
                    try {
                        byte[] buf1 = new byte[1024];
                        int len;
                        while ((len = in.read(buf1)) > 0) {
                            out.write(buf1, 0, len);
                        }
                    } finally {
                        IOUtils.closeQuietly(out);
                    }
                } finally {
                    IOUtils.closeQuietly(in);
                }
            }
            UtilLogger.debug("解压完成！ ");
        } finally {
            zip.close();
        }


    }

    /**
     * 判断是否是图片
     *
     * @param base64Str
     * @return
     */
    public static boolean isImageFromBase64(String base64Str) {
        boolean flag = false;
        try {
            BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(base64Str)));
            if (null == bufImg) {
                return flag;
            }
            flag = true;
        } catch (Exception e) {
            return flag;
        }
        return flag;
    }
}
