qvoid
11/18/2017 - 4:00 AM

Operate with files

文件操作的工具类,包含创建、解压、md5计算等

package com.evideo.kmbox.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Environment;
import android.os.FileObserver;
import android.os.StatFs;
import android.text.TextUtils;

import com.evideo.kmbox.BaseApplication;
import com.evideo.kmbox.model.file.CheckFile;
import com.evideo.kmbox.model.logagent.LogAnalyzeManagerUtil;
import com.evideo.kmbox.model.sharedpreferences.KeyName;
import com.evideo.kmbox.provider.configprovider.KmConfigManager;
import com.evideo.kmbox.update.db.UpdateDbManager;

import org.apache.http.util.EncodingUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.zip.ZipFile;

/**
 * @brief : 文件类工具
 */
@SuppressLint("SdCardPath")
@SuppressWarnings("deprecation")
public class FileUtil {
    /**
     * 缓存的大小
     */
    public static final int BUFFER_SIZE = 8192;

    /**
     * 计算视频文件MD5值大小
     */
    public static final int FIXED_MD5_LENGTH = 3 * 1024 * 1024;
    /**
     * 打开文件超时时间
     */
    private static final long OPEN_OUT_TIME = 500;

    private static final String CHARSET_GB2312 = "GB2312";
    private static final String CHARSET_8859 = "8859_1";

    /**
     * 复制整个文件夹内容
     *
     * @param oldPath String 原文件路径 如:c:/fqf
     * @param newPath String 复制后路径 如:f:/fqf/ff
     * @return boolean
     */
    public static boolean copyFolder(String oldPath, String newPath) {
        boolean ret = false;
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            // 如果文件夹不存在 则建立新文件夹
            (new File(newPath)).mkdirs();

            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()) {
                    input = new FileInputStream(temp);
                    output = new FileOutputStream(newPath
                            + "/" + (temp.getName()).toString());
                    byte[] b = new byte[1024 * 4];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if (temp.isDirectory()) {// 如果是子文件夹
                    copyFolder(oldPath + "/ " + file[i], newPath + "/ "
                            + file[i]);
                }
            }
            ret = true;
        } catch (Exception e) {
            LogAnalyzeManagerUtil.reportError(e);
            EvLog.e("--copy folder fail !--");
            e.printStackTrace();
            ret = false;
        } finally {
            try {
                if (output != null) {
                    output.close();
                }
                if (input != null) {
                    input.close();
                }
            } catch (IOException e) {
                EvLog.e("There is a unclosed file " +
                        "that will lead to resource leaks in the class");
            }
        }

        return ret;
    }

    /**
     * [功能说明]
     *
     * @param fileName 文件名
     * @return 获取文件的大小
     */
    public static long getFileSize(String fileName) {
        File file = new File(fileName);
        if (file.exists()) {
            return file.length();
        } else {
            return -1;
        }
    }

    /**
     * 获取资源库中的歌曲文件大小
     *
     * @param file File实例
     * @return double
     */
    public static double getMediFileSize(File file) {
        double size = 0;
        if (!file.exists()) {
            return size;
        }
        File[] childFiles = file.listFiles();
        if (childFiles == null || childFiles != null && childFiles.length <= 0) {
            return size;
        }
        for (int i = 0; i < childFiles.length; i++) {
            if (UpdateDbManager.isMediaFileSupport(childFiles[i])) {
                size += FileUtil.countLength(childFiles[i].getAbsolutePath());
            }
        }
        // 转化为MB
        return size / 1048576;
    }

    /**
     * 通过CMD命令计算硬盘空间大小
     *
     * @param path 路径
     * @return double
     */
    public static double countDiskSpaceByCMD(String path) {
        double countSize = 0;
        long begin = System.currentTimeMillis();
        try {
            String CMD = "busybox du -m " + path;
            Process process = Runtime.getRuntime().exec(CMD);
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    process.getInputStream()));
            String line;
            // 执行命令cmd,只取结果中含有mnt的这一行
            line = reader.readLine();
            while (line != null && line.contains("mnt") == false) {
            }
            String arr[] = line.split("\\/mnt");
            if (arr.length > 0) {
                countSize = Integer.parseInt(arr[0].toString().trim());
            }
        } catch (Exception e) {
            LogAnalyzeManagerUtil.reportError(e);
            EvLog.e("count FilesSize failure");
        }
        long end = System.currentTimeMillis();
        EvLog.d("count FilesSize use time:" + (end - begin) + "ms");
        EvLog.d("count FilesSize is:" + countSize);
        return countSize;
    }

    /**
     * [功能说明]
     *
     * @param filename       文件名
     * @param fileExpectSize 文件完整大小
     * @return 文件是否完整
     */
    public static boolean isFileComplete(String filename, long fileExpectSize) {
        boolean result = false;
        File file = new File(filename);
        if (file.exists()) {
            if (file.length() == fileExpectSize) {
                result = true;
            }
        }

        return result;
    }

    /**
     * [功能说明]
     *
     * @param fileName 文件路径
     * @return 文件是否存在
     */
    public static boolean isFileExist(String fileName) {
        File file = new File(fileName);
        if (file.exists()) {
            return true;
        }
        return false;
    }

    /**
     * @param path 文件路径
     * @return 是否是文件夹
     */
    public static boolean isDirectory(String path) {
        if (TextUtils.isEmpty(path)) {
            return false;
        }
        File file = new File(path);
        if (file.isDirectory()) {
            return true;
        }
        return false;
    }

    /**
     * [功能说明]
     *
     * @param file   文件
     * @param rename 新的文件名
     * @return 重命名后的文件名
     */
    public static File reFileName(File file, String rename) {
        if (file != null) {
            if (file.exists()) {
                String c = file.getParent();
                EvLog.d("filename", c);
                File refile = new File(c + File.separator + rename);
                if (file.renameTo(refile)) {
                    EvLog.i("FileUtil", "修改成功!");
                    file.deleteOnExit();
                    return refile;
                }
            }
        }
        EvLog.i("FileUtil", "修改失败");
        return null;
    }

    /**
     * [文件夹重命名]
     *
     * @param fromDir
     * @param toDir
     */
    public static boolean renameDirectory(String fromDir, String toDir) {

        File from = new File(fromDir);

        if (!from.exists() || !from.isDirectory()) {
            EvLog.e("Directory does not exist: " + fromDir);
            return false;
        }

        if (TextUtils.isEmpty(toDir)) {
            EvLog.e("toDir is empty: " + fromDir);
            return false;
        }

        File to = new File(toDir);

        // Rename
        if (from.renameTo(to)) {
            EvLog.d("rename dir Success!");
            return true;
        } else {
            EvLog.d("rename dir fail!");
            return false;
        }
    }

    /**
     * [功能说明] 删除文件
     *
     * @param fileName 文件名
     */
    public static boolean deleteFile(String fileName) {
        if (fileName == null)
            return false;

        File file = new File(fileName);
        if (file.exists()) {
            EvLog.d("delete file " + fileName);
            return file.delete() ? true : false;
        }
        return true;
    }

    /**
     * [功能说明] 删除文件夹下的文件
     *
     * @param dir 文件夹路径
     */
    public static void emptyDir(String dir) {
        File file = new File(dir);

        if (file.exists()) {
            if (file.isDirectory()) { // 如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    files[i].delete(); // 把每个文件 用这个方法进行迭代
                }
            }
        }
    }

    /**
     * [功能说明] 删除文件夹以及文件夹下的文件
     *
     * @param dir 文件夹路径
     */
    public static void deleteDir(String dir) {
        File file = new File(dir);
        if (file.exists()) {
            if (file.isDirectory()) { // 如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    files[i].delete(); // 把每个文件 用这个方法进行迭代
                }
            }
            file.delete();
        }
    }

    /**
     * 删除文件夹 子文件夹 文件 子文件
     * @param dir
     */
    public static void deleteAllDir(String dir){
        File file = new File(dir);

        if (file.exists()) {
            EvLog.d("file exists:" + dir);
            if (file.isDirectory()) { // 如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    EvLog.d("file exists:" + files[i].getPath());
                    deleteAllDir(files[i].getPath());
//                    files[i].delete(); // 把每个文件 用这个方法进行迭代
                }
            }
            file.delete();
        }else{
            EvLog.d("file no exists:" + dir);
        }
    }

    /**
     * [功能说明]
     *
     * @return 获取tft的路径
     */
    public static String getTtftpPath() {
        String tftppath = "/mnt/sdcard/kmbox/tftproot/";
        try {
            if (!(new File(tftppath).isDirectory())) {
                new File(tftppath).mkdir();
            }
        } catch (SecurityException e) {
            LogAnalyzeManagerUtil.reportError(e);
            e.printStackTrace();
        }
        return tftppath;
    }

    /**
     * @param path 文件夹路径
     * @brief : [删除指定文件夹下的所有文件]
     */
    public static void deleteAllFiles(String path) {
        if (path == null) {
            return;
        }
        File file = new File(path);
        if (!file.exists() || !file.isDirectory()) { // 文件不存在或不是目录
            return;
        }
        if (!file.exists()) {
            return;
        }
        if (!file.isDirectory()) {
            return;
        }
        String[] tempList = file.list();
        if (tempList == null) {
            EvLog.d("tempList null, no file in " + file.getPath());
            return;
        }
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {

            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            } else if (temp.isDirectory()) {
                deleteAllFiles(temp.getAbsolutePath());
                temp.delete();
            }

        }
    }

    /**
     * @param path 文件路径
     * @return 文件大小
     * @brief : [计算该路径对应文件或目录的长度,文件或目录不存在返回-1] 使用单线程递归方式计算
     */
    public static long countLength(String path) {
        if (path == null) {
            return -1;
        }

        File file = new File(path);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] children = file.listFiles();
                long size = 0;
                for (File f : children) {
                    size += countLength(f.getAbsolutePath());
                }
                return size;
            } else if (file.isFile()) {
                return file.length();
            }
        }

        return -1;
    }

    /**
     * @param path 路径
     * @return 可用空间大小
     * @brief : [获取可用空间大小]
     */
    public static long getAvailableSize(String path) {
        long time = System.currentTimeMillis();
        File file = new File(path);
        if (!file.exists() || !file.isDirectory()) {
            return -1;
        }
        StatFs statFs = new StatFs(path);
        long blockSize = statFs.getBlockSize();
        long availableBlocks = statFs.getAvailableBlocks();
        long size = blockSize * availableBlocks;
        long countTime = (System.currentTimeMillis() - time);
        if (countTime > 10) {
            EvLog.w("getAvailableSize count time:" + countTime +"  size:" + size + "  path:" + path);
        }
        return size;
    }

    /**
     * 在限定时间内获取硬盘剩余空间大小
     * @param path
     * @return
     */
    public static long getAvailableSizeInTime(final String path){
        long avialableSize = -1;
        ExecutorService executor = Executors.newSingleThreadExecutor();
        FutureTask<Long> future =
                new FutureTask<Long>(new Callable<Long>() {
                    public Long call() {
                        return getAvailableSize(path);
                    }});
        executor.execute(future);
        try {
            //限定500ms执行完,正常情况下 10ms内能执行完
            avialableSize = future.get(OPEN_OUT_TIME, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            avialableSize = -1;
            future.cancel(true);
            EvLog.e("getAvailableSizeInTime InterruptedException");
            LogAnalyzeManagerUtil.reportError("getAvailableSizeInTime InterruptedException");
        } catch (ExecutionException e) {
            avialableSize = -1;
            future.cancel(true);
            EvLog.e("getAvailableSizeInTime ExecutionException");
            LogAnalyzeManagerUtil.reportError("getAvailableSizeInTime ExecutionException");
        } catch (TimeoutException e) {
            avialableSize = -1;
            future.cancel(true);
            EvLog.e("getAvailableSizeInTime TimeoutException");
            LogAnalyzeManagerUtil.reportError("getAvailableSizeInTime TimeoutException");
        } finally {
            executor.shutdown();
        }
        return avialableSize;
    }

    /**
     * @param context 上下文
     * @param path    路径
     * @return 总空间大小
     * @brief : [获取格式化后的可用空间大小]
     */
    public static String getAvailableFormatSize(Context context, String path) {
        long size = getAvailableSize(path);
        if (size < 0) {
            return null;
        }
        return FileSizeFormatter.formatFileSize(context, size);
    }

    /**
     * @param path 路径
     * @return 总大小
     * @brief : [获取总大小]
     */
    public static long getTotalSize(String path) {
        File file = new File(path);
        if (!file.exists() || !file.isDirectory()) {
            return -1;
        }
        StatFs statFs = new StatFs(path);
        long blockSize = statFs.getBlockSize();
        long blockCount = statFs.getBlockCount();
        return blockSize * blockCount;
    }

    /**
     * @param context 上下文
     * @param path    路径
     * @return 总格式化后的大小
     * @brief : [获取格式化后的总大小]
     */
    public static String getTotalFormatSize(Context context, String path) {
        long size = getTotalSize(path);
        if (size < 0) {
            return null;
        }
        return FileSizeFormatter.formatFileSize(context, size);
    }

    /**
     * @param path   路径
     * @param append 路径
     * @return 拼接后的路径
     * @brief : [组合路径]
     */
    public static String concatPath(String path, String append) {
        if (path == null) {
            return null;
        }
        String temp = null;
        if (path.endsWith(File.separator)) {
            temp = path + append;
        } else {
            temp = path + File.separator + append;
        }
        return temp;
    }

    /**
     * @param zipFilePath    需要压缩的文件夹名
     * @param newzipFileName
     * @throws IOException
     * @brief : [压缩文件夹内的文件 ]
     */
    public static void doZip(String zipFilePath, String newzipFileName)
            throws IOException {

        if (!FileUtil.isFileExist(zipFilePath)) {
            return;
        }

        File zipFile;
        ZipOutputStream zipOut = null; // 压缩Zip

        zipFile = new File(zipFilePath);
        String zipFileName = zipFile.getParent() + "/" + newzipFileName;// 压缩后生成的zip文件名

        try {
            zipOut = new ZipOutputStream(new BufferedOutputStream(
                    new FileOutputStream(zipFileName)));
            handleDir(zipFile, zipOut);
        } finally {
            if (zipOut != null) {
                zipOut.closeEntry();
                zipOut.close();
            }
        }
    }

    // 由doZip调用,递归完成目录文件读取
    private static void handleDir(File dir, ZipOutputStream zipOut)
            throws IOException {
        FileInputStream fileIn = null;
        File[] files = null;
        byte[] buf = new byte[512];
        int readedBytes;

        if (dir.isDirectory()) {
            files = dir.listFiles();
        } else {
            files = new File[1];
            files[0] = dir;
        }

        if (files.length == 0) {// 如果目录为空,则单独创建之.
            // ZipEntry的isDirectory()方法中,目录以"/"结尾.
            zipOut.putNextEntry(new ZipEntry(dir.toString() + "/"));
            zipOut.closeEntry();
        } else {// 如果目录不为空,则分别处理目录和文件.
            for (File fileName : files) {

                if (fileName.isDirectory()) {
                    handleDir(fileName, zipOut);
                } else {
                    try {
                        fileIn = new FileInputStream(fileName);
                        zipOut.putNextEntry(new ZipEntry(fileName.getName()));

                        while ((readedBytes = fileIn.read(buf)) > 0) {
                            zipOut.write(buf, 0, readedBytes);
                        }
                        zipOut.closeEntry();
                    }finally {
                        if(fileIn != null){
                            try {
                                fileIn.close();
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    }

                }
            }
        }
    }

    /**
     * [功能说明]
     *
     * @param path 文件路径
     * @return 返回读取到的文本
     * @throws IOException 文件读取异常
     */
    public static String readFile(String path) throws IOException {
        String fileContent = "";
        if (TextUtils.isEmpty(path)) {
            return fileContent;
        }

        FileInputStream fin = null;

        try {
            fin = new FileInputStream(path);
            int length = fin.available();
            byte[] buffer = new byte[length];
            fin.read(buffer);
            fileContent = EncodingUtils.getString(buffer, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fin != null) {
                fin.close();
            }
        }
        // System.out.println("DatabaseTool:"+fileContent);
        return fileContent;
    }

    /**
     * [获取文件行数]
     *
     * @param file 文件路径
     * @return
     * @throws IOException
     */
    public static int getTotalLines(File file) throws IOException {
        int lines = 0;
        FileReader in = null;

        try {
            in = new FileReader(file);
            LineNumberReader reader = new LineNumberReader(in);
            String s = reader.readLine();
            while (s != null) {
                lines++;
                s = reader.readLine();
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                EvLog.e("There is a unclosed file " +
                        "that will lead to resource leaks in the class");
            }
        }
        return lines;
    }

    /**
     * [根据行读取文件]
     *
     * @param sourceFile
     * @param lineNumber 行号从1开始
     * @throws IOException
     */
    @SuppressWarnings("unused")
    public static String readFileLineNumber(String sourceFile, int lineNumber)
            throws IOException {
        File file = new File(sourceFile);
        if (file == null) {
            EvLog.e("the file is null!");
            return "";
        }
        String out = "";
        FileReader in = null;
        try {
            in = new FileReader(file);
            LineNumberReader reader = new LineNumberReader(in);
            String s = "";
            if (lineNumber <= 0 || lineNumber > getTotalLines(file)) {
                EvLog.e("the lineNumber is out of range!");
            }
            int lines = 0;
            while (s != null) {
                lines++;
                s = reader.readLine();
                if ((lines - lineNumber) == 0) {
                    out = s;
                    break;
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                EvLog.e("There is a unclosed file " +
                        "that will lead to resource leaks in the class");
            }
        }
        return out;
    }

    /**
     * [功能说明]
     *
     * @param fileName 文件名
     * @param message  写入内容
     * @param append   是否追加
     * @throws IOException 抛出异常
     */
    public static boolean writeFile(String fileName, String message, boolean append)
            throws IOException {
        boolean ret = false;
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(fileName, append)));
            out.write(message);
            ret = true;
        } catch (Exception e) {
            // e.printStackTrace();
            ret = false;
            LogAnalyzeManagerUtil.reportError(e);
            EvLog.e("write file fail !");
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                ret = true;
            } catch (IOException e) {
                ret = false;
                LogAnalyzeManagerUtil.reportError(e);
                EvLog.e("write file ,close stream fail !");
            }
        }
        return ret;
    }

    /**
     * [功能说明]
     *
     * @param fileName
     * @return
     * @throws IOException
     */
    public static File creatSDFile(String fileName) throws IOException {
        File file = new File(fileName);
        file.createNewFile();
        return file;
    }

    /**
     * [功能说明] 创建文件夹
     *
     * @param path 要创建的文件夹路径
     */
    public static void createDir(String path) {
        File saveFile = new File(path);
        if (!saveFile.exists()) {
            saveFile.mkdirs();
        }
    }

    /**
     * [功能说明] 从Asset拷贝文件到指定路径
     *
     * @param fromPath asset下的路径
     * @param toPath   拷贝到的路径
     */
    public static void copyFromAsset(String fromPath,
                                     String toPath) {

        if (TextUtils.isEmpty(fromPath) || TextUtils.isEmpty(toPath)) {
            EvLog.e("--copyFromAsset param is error!--");
            return;
        }

        InputStream is = null;
        try {
            is = BaseApplication.getInstance().getBaseContext().getAssets().open(fromPath);
        } catch (IOException e1) {
            LogAnalyzeManagerUtil.reportError(e1);
            // TODO Auto-generated catch block
            return;
        }

        byte[] buffer = new byte[BUFFER_SIZE];
        int count = 0;
        FileOutputStream os = null;
        try {
            os = new FileOutputStream(toPath);
            // 输出流判空
            if (os == null) {
                EvLog.e("--copyFromAsset outstream is null!--");
                return;
            }

            while ((count = is.read(buffer)) > 0) {
                os.write(buffer, 0, count);
                os.flush();
            }
        } catch (IOException e) {
            LogAnalyzeManagerUtil.reportError(e);
        }

        try {
            is.close();
            if (os != null) {
                os.close();
            }
        } catch (Exception e) {
            LogAnalyzeManagerUtil.reportError(e);
        }
    }

    /**判断asset 特定是否有文件
     * @param fileName
     * @return
     */
    public static boolean isAssetsFileExit(String fileName){
        boolean ret = false;
        AssetManager am = BaseApplication.getInstance().getBaseContext().getAssets();
        if (am == null) {
            EvLog.e("--isAssetsFileExit am null--");
            return ret;
        }
        try {
            String[] names = am.list("");
            for (int i = 0; i < names.length; i++) {
                String name = names[i];
                if (name != null) {
                    EvLog.d("--name is :" + name);
                    if (name.equals(fileName.trim())) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            EvLog.e("--check isAssetsFileExit error:--" + e);
        }
        return ret;
    }


    /**
     * @return SD卡剩余空间大小
     */
    public static Long getSDAvailableSize() {
        File path = Environment.getExternalStorageDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long availableBlocks = stat.getAvailableBlocks();
        return blockSize * availableBlocks;
    }

    /**
     * @param fromPath 源文件
     * @param toPath   目标文件
     * @return 复制成功或者失败
     */
    @SuppressWarnings("resource")
    public static boolean copyFile(String fromPath, String toPath) {
        boolean ret = true;
        FileOutputStream os = null;
        // 如果目标文件不存在,创建
        if (!isFileExist(toPath)) {
            createFile(toPath);
        }
        try {
            if (isDirectory(toPath)) {
                File file = new File(fromPath);
                os = new FileOutputStream(toPath + "/" + file.getName());
            } else {
                os = new FileOutputStream(toPath);
            }
        } catch (FileNotFoundException e) {
            LogAnalyzeManagerUtil.reportError(e);
            return false;
        }
        FileInputStream is = null;
        try {
            // is = mContext.getAssets().open(fromPath);
            is = new FileInputStream(fromPath);
        } catch (IOException e1) {
            LogAnalyzeManagerUtil.reportError(e1);
            // TODO Auto-generated catch block
            return false;
        }

        byte[] buffer = new byte[BUFFER_SIZE];
        int count = 0;
        try {
            while ((count = is.read(buffer)) > 0) {
                os.write(buffer, 0, count);
                os.flush();
            }
        } catch (IOException e) {
            LogAnalyzeManagerUtil.reportError(e);
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                LogAnalyzeManagerUtil.reportError(e);
                return ret;
            }
        }
        return ret;
    }

    /**
     * [获取文件的MD5值]
     *
     * @param file 文件路径
     * @return MD5值
     * @throws FileNotFoundException 文件未找到异常
     */
    public static String getMd5ByFile(File file) throws FileNotFoundException {
        String value = null;
        FileInputStream in = new FileInputStream(file);
        try {
            MappedByteBuffer byteBuffer = in.getChannel().map(
                    FileChannel.MapMode.READ_ONLY, 0, file.length());
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(byteBuffer);
            BigInteger bi = new BigInteger(1, md5.digest());
//            value = bi.toString(16);
            value = String.format("%032x", bi);
        } catch (Exception e) {
            // e.printStackTrace();
            LogAnalyzeManagerUtil.reportError(e);
            EvLog.e("---getMd5ByFile exception1--");
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    // e.printStackTrace();
                    LogAnalyzeManagerUtil.reportError(e);
                    EvLog.e("---getMd5ByFile exception2--");
                }
            }
        }
        return value;
    }

    /**
     * 获取单个文件的MD5值!
     *
     * @param file 文件
     * @return md5值
     */

    public static String getFileMD5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        byte buffer[] = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                EvLog.e("There is a unclosed file " +
                        "that will lead to resource leaks in the class");
            }
        }
        BigInteger bigInt = new BigInteger(1, digest.digest());
        return bigInt.toString(16);
    }

    /**
     * [获取文件扩展名]
     *
     * @param filePath 文件名
     * @return String 扩展名
     */
    public static String getFileExt(String filePath) {
        if (filePath == null) {
            return null;
        }

        int pos = filePath.indexOf(".");
        if (pos < 0 || pos >= filePath.length()) {
            return null;
        }

        return filePath.substring(filePath.indexOf(".") + 1);
    }

    /**
     * [获取某文件的byte数组]
     *
     * @param filePath 文件的路径
     * @return byte[]
     */
    public static byte[] getFileByteArray(String filePath) {
        FileInputStream is = null;
        try {
            is = new FileInputStream(new File(filePath));
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            int nRead;
            byte[] data = new byte[8 * 1024];
            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }
            buffer.flush();
            is.close();
            return buffer.toByteArray();
        } catch (FileNotFoundException e2) {
            LogAnalyzeManagerUtil.reportError(e2);
            // TODO Auto-generated catch block
        } catch (IOException e1) {
            LogAnalyzeManagerUtil.reportError(e1);
            // TODO Auto-generated catch block
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                EvLog.e("There is a unclosed file " +
                        "that will lead to resource leaks in the class");
            }
        }
        return null;
    }

    /**
     * [获取文件的MD5值]
     *
     * @param file 文件路径
     * @return MD5值
     * @throws FileNotFoundException 文件未找到异常
     */
    public static String getMd5ByFilePartial(File file) throws Exception {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        int size = (int) Math.min(file.length(), FIXED_MD5_LENGTH);
        byte buffer[] = new byte[size];
        int len;

        int readLenght = size;
        digest = MessageDigest.getInstance("MD5");
        in = new FileInputStream(file);
        try {
            while ((len = in.read(buffer, 0, readLenght)) != -1) {
                digest.update(buffer, 0, len);
                readLenght -= len;
                if (readLenght <= 0) {
                    break;
                }
            }
        } catch(Exception e) {
            EvLog.e("--getMd5ByFilePartial error--" + e);
        } finally {
            if (in != null) {
                in.close();
            }
        }

        BigInteger bigInt = new BigInteger(1, digest.digest());
        String md5 = bigInt.toString(16);

        if (md5.length() != 32) {
            for (int i = md5.length(); i < 32; i++) {
                md5 += "0";
            }
        }
        return md5;
    }

    /**
     * 重命名文件
     *
     * @param sourcePath
     * @param destName
     * @return
     */
    public static boolean renameFile(String sourcePath, String destName) {
        if (sourcePath == null || destName == null) {
            return false;
        }
        File sourceFile = new File(sourcePath);
        if (!sourceFile.exists()) {
            return false;
        }

        String c = sourceFile.getParent();
        File refile = new File(c + File.separator + destName);
        if (sourceFile.renameTo(refile)) {
            EvLog.i("FileUtil", "renameFile 修改成功!");
            sourceFile.deleteOnExit();
        }
        return true;
    }

    /**
     * @param sourcePath 源文件路径
     * @param destName   目标文件路径
     * @return true成功 false失败
     */
    public static boolean renameFileFullpath(String sourcePath, String destName) {
        if (sourcePath == null || destName == null) {
            return false;
        }
        File sourceFile = new File(sourcePath);
        if (!sourceFile.exists()) {
            return false;
        }

        @SuppressWarnings("unused")
        String c = sourceFile.getParent();
        File refile = new File(destName);
        if (sourceFile.renameTo(refile)) {
            EvLog.i("FileUtil", "renameFileFullpath 重命名成功!");
            sourceFile.deleteOnExit();
            return true;
        }
        EvLog.i("FileUtil", "renameFileFullpath 重命名失败!");
        return false;
    }

    public static boolean createFile(String destFileName) {
        if (TextUtils.isEmpty(destFileName)) {
            EvLog.w("--destFileName is null--");
            return false;
        }
        // 保证sdcard至少有100M空间
        cleanSdCard(100);

        File file = new File(destFileName);
        if (file.exists()) {
            EvLog.i("创建单个文件" + destFileName + "失败,目标文件已存在!");
            return false;
        }
        if (destFileName.endsWith(File.separator)) {
            EvLog.e("创建单个文件" + destFileName + "失败,目标文件不能为目录!");
            return false;
        }
        // 判断目标文件所在的目录是否存在
        if (!file.getParentFile().exists()) {
            // 如果目标文件所在的目录不存在,则创建父目录
            EvLog.i("目标文件所在目录不存在,准备创建它!");
            if (!file.getParentFile().mkdirs()) {
                EvLog.e("创建目标文件所在目录失败!");
                return false;
            }
        }
        // 创建目标文件
        try {
            if (file.createNewFile()) {
                EvLog.i("创建单个文件" + destFileName + "成功!");
                return true;
            } else {
                EvLog.e("创建单个文件" + destFileName + "失败!");
                return false;
            }
        } catch (IOException e) {
            LogAnalyzeManagerUtil.reportError(e);
            e.printStackTrace();
            EvLog.e("创建单个文件" + destFileName + "失败!" + e.getMessage());
            return false;
        }
    }

    /**
     * 移动文件
     *
     * @param srcFileName 源文件完整路径
     * @param destDirName 目的目录完整路径
     * @return 文件移动成功返回true,否则返回false
     */
    public static boolean moveFile(String srcFileName, String destDirName) {

        File srcFile = new File(srcFileName);
        if (!srcFile.exists() || !srcFile.isFile()) {
            return false;
        }
        String destPath = destDirName + File.separator + srcFile.getName();
        EvLog.d("dest path:" + destPath);
        return srcFile.renameTo(new File(destPath));
    }

    public static boolean renameFileWithPath(String sourcePath, String destPath) {
        if (TextUtils.isEmpty(sourcePath) || TextUtils.isEmpty(destPath)) {
            return false;
        }
        File sourceFile = new File(sourcePath);
        if (!sourceFile.exists()) {
            return false;
        }

        @SuppressWarnings("unused")
        String c = sourceFile.getParent();
        File refile = new File(destPath);
        if (sourceFile.renameTo(refile)) {
            EvLog.i("FileUtil", "rename success");
            sourceFile.deleteOnExit();
        } else {
            EvLog.e("FileUtil", "rename failed!");
            return false;
        }
        return true;
    }

    private static final String RM_SH = "/mnt/sdcard/kmbox/rm.sh";
    /**
     * @param path       待删除文件所在目录
     * @param suffixName 指定后缀名 例如存储盘下“.tmp”临时文件
     * @return true成功, false失败
     */
    public static boolean deleteSuffixFile(String path, String suffixName,String excludeFile) {
        String rmCommond;
        if (TextUtils.isEmpty(excludeFile)){
            rmCommond = "rm " + path   + suffixName;
        }else {
            rmCommond = "rm `ls " + path + suffixName + " | grep -v " + excludeFile + "`";
        }
        EvLog.d("rmCommond:" + rmCommond);
        try {
            reCreateRmSh(rmCommond);
        } catch (IOException e) {
            e.printStackTrace();
            EvLog.e("reCreateRmSh failed:" + e);
            return false;
        }

        try {
            Runtime.getRuntime().exec("/system/bin/sh " + RM_SH);
        } catch (IOException e) {
            EvLog.e("implement rm failed:" + e);
            return false;
        }
        return true;
    }

    // 重写rm命令
    private static void reCreateRmSh(String commond) throws IOException {
        // 删除再重新创建
        File f = new File(RM_SH);
        if (f.exists()) {
            f.delete();
        }
        f.createNewFile();
        // 修改为777权限
        try {
            Runtime.getRuntime().exec("chmod 777 " + RM_SH);
        } catch (IOException e) {
            EvLog.e("reCreateRmSh failed!");
        }

        FileWriter writer = null;
        try {
            writer = new FileWriter(RM_SH, true);
            writer.write(commond);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    /**
     * [功能说明]单位为M
     */
    public static void cleanSdCard(long needFreeSize) {
        long freeSize = 1024 * 1024 * needFreeSize;
        long leftSize = 0;
        boolean isDebug = KmConfigManager.getInstance().getBoolean(
//        boolean isDebug = KmSharedPreferences.getInstance().getBoolean(
                KeyName.KEY_DEBUG_MODE_SWITCH, false);

        String path = Environment.getExternalStorageDirectory().getPath();

        //删除无用路径
        FileUtil.deleteAllFiles(path + "/360Download");
        FileUtil.deleteAllFiles(path + "/wandoujia/app/");

        leftSize = FileUtil.getAvailableSize(path);
        if (leftSize < freeSize) {
            EvLog.e("-------left size is ---------" + leftSize);
            FileUtil.deleteAllFiles(path + "/LOST.DIR");
            FileUtil.deleteAllFiles(path + "/download");
        } else {
            return;
        }

        leftSize = FileUtil.getAvailableSize(path);
        if (leftSize < freeSize) {
            EvLog.e("-------left size is ---------" + leftSize);
            FileUtil.deleteAllFiles(path + "/android");
        } else {
            return;
        }

        // 小于设定空间自动清除文件,debug 模式不能清log
        if (!isDebug) {
            leftSize = FileUtil.getAvailableSize(path);
            if (leftSize < freeSize ) {
                EvLog.e("-------left size is ---------" + leftSize);
                FileUtil.deleteAllFiles(path + "/kmbox/log");
            } else {
                return;
            }
        }

        leftSize = FileUtil.getAvailableSize(path);
        if (leftSize < freeSize) {
            EvLog.e("-------left size is ---------" + leftSize);
            FileUtil.deleteAllFiles(path + "/kmbox/records");
        } else {
            return;
        }

        leftSize = FileUtil.getAvailableSize(path);
        if (leftSize < freeSize){
            EvLog.e("-------left size is ---------" + leftSize);
            FileUtil.deleteAllFiles(path + "/kmbox/template/download");
        } else {
            return;
        }
    }

    /**
     * 修改文件权限为777
     * @param path
     */
    public static void modifyPermission(String path){
        try {
            Runtime.getRuntime().exec(
                    "chmod 777 " + path);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            LogAnalyzeManagerUtil.reportError(e);
            EvLog.e("Modify permissions failure");
        }
    }

    /**将文件名后缀去除
     * @param fileName
     * @return
     */
    public static String getFileNameWithoutSuffix(String fileName) {
        if (TextUtils.isEmpty(fileName)) {
            return "";
        }
        char standard = '.';
        int index = 0;
        for (int i = 0; i < fileName.length(); i++) {
            if (fileName.charAt(i) == standard) {
                // 确保是最后一个“.”
                index = i;
            }
        }
        // 获取文件名
        fileName = fileName.substring(0, index);

        return fileName;
    }

    /*判断文件夹是否存在文件
     * @param path
     * @return
     */
    public static boolean isFolderHaveFile(String path) {
        boolean ret = false;
        if (TextUtils.isEmpty(path)) {
            EvLog.w("--path is null !!--");
            return ret;
        }
        File file = new File(path);
        if (file != null && file.exists()&& file.isDirectory()){
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                return true;
            } else {
                EvLog.e("--there is no file--");
            }
        } else {
            EvLog.d("--this path is not folder !--");
        }
        return ret;
    }

    public static boolean hasZeroSizeFile(String path){
        CheckFile checkFile = new CheckFile();
        boolean has =  checkFile.hasZeroSizeFile(path);
        EvLog.d("hasZeroSizeFile path:" + path + " has?" + has);
        return has;
    }

    public static int upZipFile(File zipFile, String folderPath) throws IOException {
        File folder = new File(folderPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        ZipFile zfile = new ZipFile(zipFile);
        Enumeration zList = zfile.entries();
        java.util.zip.ZipEntry ze;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            ze = (java.util.zip.ZipEntry) zList.nextElement();
            if (ze.isDirectory()) {
                String dirstr = folderPath + ze.getName();
                dirstr = new String(dirstr.getBytes(CHARSET_8859),
                        CHARSET_GB2312);
                File f = new File(dirstr);
                f.mkdir();
                continue;
            }
            OutputStream os = new BufferedOutputStream(new FileOutputStream(
                    getRealFileName(folderPath, ze.getName())));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
        }
        zfile.close();
        return 0;
    }

    private static File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr = "";
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                modifyCharset(substr);
                ret = new File(ret, substr);

            }
            if (!ret.exists()) {
                ret.mkdirs();
            }
            substr = dirs[dirs.length - 1];
            modifyCharset(substr);
            ret = new File(ret, substr);
            return ret;
        }
        return ret;
    }

    /**
     * [功能说明] 修改字符串编码类型
     *
     * @param substr 要修改的字符串
     */
    private static void modifyCharset(String substr) {
        try {
            substr = new String(substr.getBytes(CHARSET_8859), CHARSET_GB2312);
        } catch (UnsupportedEncodingException e) {
            LogAnalyzeManagerUtil.reportError(e);
            EvLog.e("UnsupportedEncodingException substr");
        }
    }

    /**
     * [root 文件授权 RootCmd("chmod 777 /dev/input/event3");]
     * @param cmd
     * @return
     */
    public static boolean RootCmd(String cmd){
        Process process = null;
        DataOutputStream os = null;
        try{
            process = Runtime.getRuntime().exec("su") ;
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd+ "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e) {
            return false;
        } finally {
            try {
                if (os != null)   {
                    os.close();
                }
                process.destroy();
            } catch (Exception e) {
            }
        }
        return true;
    }

    /**
     * SD卡中的目录创建监听器。
     *
     * @author mayingcai
     */
    public static class FileListener extends FileObserver {

        public FileListener(String path) {
              /*
               * 这种构造方法是默认监听所有事件的,如果使用 super(String,int)这种构造方法,
               * 则int参数是要监听的事件类型.
               */
            super(path);
        }

        @Override
        public void onEvent(int event, String path) {
            switch(event) {
                case FileObserver.ALL_EVENTS:
                    EvLog.d("FileListenerall", "path:"+ path);
                    break;
                case FileObserver.CREATE:
                    EvLog.d("FileListenerCreate", "path:"+ path);
                    break;
            }
        }
    }
}