package com.baidu.ai.sample.util;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.baidu.ai.sample.BuildConfig;
import com.baidu.ai.sample.data.ContextConstant;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.Closeable;
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.OutputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 文件操作工具类
 */
public class FileUtils {

    /**
     * 从文件读取byte数组
     *
     * @param fileName
     * @return
     */
    public static byte[] loadDataFromFile(String fileName) {
        InputStream is = null;
        try {
            is = new FileInputStream(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return loadDataFromStream(is);
    }

    /**
     * 从assets读取byte数组
     *
     * @param context
     * @param fileName
     * @return
     */
    public static byte[] loadDataFromAssets(Context context, String fileName) {
        if (context == null) {
            return null;
        }
        InputStream is = null;
        try {
            is = context.getAssets().open(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return loadDataFromStream(is);
    }

    /**
     * 从流中读取byte数组
     *
     * @param is
     * @return
     */
    public static byte[] loadDataFromStream(InputStream is) {
        if (is == null) {
            return null;
        }
        try {
            byte[] itemData = new byte[is.available()];
            int len = is.read(itemData);
            return itemData;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 是否挂载Sdcard
     *
     * @return
     */
    public static boolean isSDMounted() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    public static boolean copyFile(String oldPath, String newPath) throws IOException {
        return copyFile(oldPath, newPath, null);
    }

    public static boolean copyFile(String oldPath, String newPath,
                                   OnVideoMergeProgressListener listener) throws IOException {
        InputStream inStream = new FileInputStream(oldPath);
        return copyFile(inStream, newPath, listener);
    }

    /**
     * 复制文件
     *
     * @param srcFile
     * @param destFile
     * @return
     * @throws IOException
     */
    public static boolean copyFile(File srcFile, File destFile) throws IOException {
        if (srcFile == null) {
            return false;
        } else if (destFile == null) {
            return false;
        } else if (!srcFile.exists()) {
            return false;
        } else if (srcFile.isDirectory()) {
            return false;
        } else if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
            return false;
        } else {
            File parentFile = destFile.getParentFile();
            if (parentFile != null && !parentFile.mkdirs() && !parentFile.isDirectory()) {
                return false;
            } else if (destFile.exists() && !destFile.canWrite()) {
                return false;
            } else {
                return doCopyFile(srcFile, destFile);
            }
        }
    }

    public static boolean copyFile(InputStream inStream, String newPath,
                                   OnVideoMergeProgressListener listener) throws IOException {
        try {
            double fileSize = 0;
            if (inStream instanceof FileInputStream) {
                fileSize = ((FileInputStream) inStream).getChannel().size();
            }
            int byteSum = 0;
            int byteRead = 0;
            FileOutputStream fs = new FileOutputStream(newPath);
            byte[] buffer = new byte[1444];
            while ((byteRead = inStream.read(buffer)) != -1) {
                byteSum += byteRead;
                if (listener != null && fileSize != 0) {
                    listener.onUpdateProgress((int) (byteSum / fileSize * 100));
                } else if (listener != null && fileSize == 0) {
                    listener.onUpdateProgress(80);
                }
                fs.write(buffer, 0, byteRead);
            }
            return true;
        } finally {
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static boolean delete(File file) {
        if (file == null) {
            return false;
        } else {
            deleteNotCheck(file);
            return !file.exists();
        }
    }

    private static void deleteNotCheck(File file) {
        if (file.isFile()) {
            file.delete();
        } else {
            File[] childList = file.listFiles();
            if (childList != null && childList.length != 0) {
                File[] var2 = childList;
                int var3 = childList.length;

                for (int var4 = 0; var4 < var3; ++var4) {
                    File f = var2[var4];
                    deleteNotCheck(f);
                    file.delete();
                }

            } else {
                file.delete();
            }
        }
    }

    /**
     * 删除某个文件夹下所有文件，注意不支持删除子文件夹
     *
     * @param dir
     */
    public static void deleteAllFiles(File dir) {
        if (dir == null) {
            return;
        }
        File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }

        for (File file : files) {
            if (!file.isDirectory()) {
                file.delete();
            }
        }
    }

    /**
     * 删除所有文件，除了某个文件
     *
     * @param dir
     * @param exceptFileName
     */
    public static void deleteAllFiles(File dir, String exceptFileName) {
        if (dir == null) {
            return;
        }
        File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            if (!TextUtils.equals(exceptFileName, file.getAbsolutePath())) {
                file.delete();
            }
        }
    }

    /**
     * 删除文件集合，包括文件的子目录页一起删除
     *
     * @param fliesList
     */
    public static void deleteFiles(List<File> fliesList) {
        if (fliesList == null || fliesList.size() == 0) {
            return;
        }
        for (int i = 0; i < fliesList.size(); i++) {
            File file = fliesList.get(i);
            if (file != null && file.exists()) {
                deleteDir(file);
            }
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     *
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     * If a deletion fails, the method stops attempting to
     * delete and returns "false".
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            // 递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    /**
     * 文件删除
     *
     * @param path 需要删除的文件
     * @return 删除成功或文件不存在返回true，删除失败返回false
     */
    public static boolean deleteFile(String path) {
        boolean delResult = true;
        if (TextUtils.isEmpty(path)) {
            // 文件不存在不需要删除
            return delResult;
        }
        try {
            File f = new File(path);
            if (f.exists()) {
                // 文件需要删除
                delResult = f.delete();
            }
        } catch (Exception e) {
            // 删除失败
            delResult = false;
            e.printStackTrace();
        }
        return delResult;
    }

    public static boolean deleteFile(File f) {
        boolean isSuccess = false;
        try {
            if (f.delete()) {
                isSuccess = true;
            }
        } catch (Exception ex) {
            isSuccess = false;
        }
        return isSuccess;
    }

    /**
     * 读取文本
     *
     * @param filename
     * @param content
     */
    public static boolean saveText(String filename, String content) {
        if (TextUtils.isEmpty(filename)) {
            return false;
        }
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(filename);
            output.write(content.getBytes());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null) {
                    output.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 保存文本
     *
     * @param file
     * @return
     */
    public static String readText(File file) {
        if (file == null || !file.exists()) {
            return null;
        }
        try {
            FileInputStream input = new FileInputStream(file);
            return readText(input);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String readText(InputStream input) {
        if (input == null) {
            return null;
        }
        try {
            StringBuilder sb = new StringBuilder();
            InputStreamReader isr = new InputStreamReader(input);
            BufferedReader br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 获取url的后缀
     *
     * @param url
     * @return
     */
    public static String getFileFormat(String url) {
        if (TextUtils.isEmpty(url)) {
            return null;
        }
        int pos = url.lastIndexOf(".");
        if (pos > 0) {
            return url.substring(pos + 1);
        }
        return null;
    }

    /**
     * 获取文件是否存在
     */

    public static boolean getExistFile(File file) {

        if (file.exists()) {
            return true;
        }
        return false;
    }

    public static boolean isExists(String path) {
        try {
            return new File(path).exists();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static long getDurationOfVideoInUs(String inputPath) {
        long duration = -1L;
        MediaExtractor extractor = null;
        try {

            extractor = new MediaExtractor();
            extractor.setDataSource(inputPath);

            for (int i = 0; i < extractor.getTrackCount(); i++) {
                MediaFormat format = extractor.getTrackFormat(i);
                if (format.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
                    // if you want to keep original width and height
                    duration = format.getLong(MediaFormat.KEY_DURATION);
                    break;
                }
            }

        } catch (Exception e) {
            Log.e("FileUtils", Log.getStackTraceString(e));
        } finally {
            if (extractor != null) {
                extractor.release();
            }
        }
        return duration;
    }


    /**
     * 根据uri 获取到path；
     *
     * @param uri
     * @return
     */
    public static String getPath(Context context, final Uri uri) {
        try {
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
//                if (isExternalStorageDocument(uri)) {
//                    final String docId = DocumentsContract.getDocumentId(uri);
//                    final String[] split = docId.split(":");
//                    final String type = split[0];
//                    if ("primary".equalsIgnoreCase(type)) {
//                        return Environment.getExternalStorageDirectory() + "/" + split[1];
//                    }
//                } else
                if (isDownloadsDocument(uri)) {
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content" +
                                    "://downloads/public_downloads"),
                            Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                } else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];

                    Uri contentUri = null;
                    switch (type) {
                        case "image":
                            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                            break;
                        case "video":
                            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                            break;
                        case "audio":
                            contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                            break;
                        default:
                            contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }

                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{
                            split[1]
                    };

                    return getDataColumn(context, contentUri, selection, selectionArgs);
                }
            } else if ("content".equalsIgnoreCase(uri.getScheme())) {
                return getDataColumn(context, uri, null, null);
            } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
        } catch (Exception e) {
            // inside
        }
        return null;
    }


    /**
     * 是否media
     *
     * @param uri
     * @return
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }


    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }


    /**
     * @param context
     * @param uri
     * @param selection
     * @param selectionArgs
     * @return
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {
        Cursor cursor = null;
        final String column = MediaStore.Images.Media.DATA;
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs
                    , null);
            if (cursor != null && cursor.moveToFirst()) {
                final int columnIndex = cursor.getColumnIndexOrThrow(column);
                String value = cursor.getString(columnIndex);
                if (value.startsWith("content://") || !value.startsWith("/") && !value.startsWith("file://")) {
                    return null;
                }
                return value;
            }
        } catch (Exception ignore) {
            ignore.printStackTrace();
            // inside
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }

    public static void deleteFileOrDir(File file) {
        try {
            if (file.exists()) {
                if (file.isDirectory()) {
                    File[] files = file.listFiles();
                    for (int i = 0, len = files.length; i < len; i++) {
                        if (files[i].isFile()) {
                            files[i].delete();
                        } else {
                            deleteFileOrDir(files[i]);
                        }
                    }
                }
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param fileName
     * @return
     */
    public static boolean isExistFile(String fileName) {
        if (!TextUtils.isEmpty(fileName)) {
            return new File(fileName).exists();
        }
        return false;
    }

    public interface OnVideoMergeProgressListener {
        void onUpdateProgress(int progress);

        void onPtsTime(long ptsTime);

        void onUpdateProgressFinished();
    }

    public static long getFileLength(String filePath) {
        try {
            File file = new File(filePath);
            if (file.exists()) {
                return file.length();
            }
        } catch (Exception var2) {
            var2.printStackTrace();
        }

        return 0L;
    }

    public static FileInputStream openFileInputStream(String filePath) throws IOException {
        File file = new File(filePath);
        if (file.exists()) {
            if (file.isDirectory()) {
                throw new IOException("File '" + file + "' exists but is a directory");
            } else if (!file.canRead()) {
                throw new IOException("File '" + file + "' cannot be read");
            } else {
                return new FileInputStream(file);
            }
        } else {
            throw new FileNotFoundException("File '" + file + "' does not exist");
        }
    }

    public static FileOutputStream openFileOutputStream(String filePath) throws IOException {
        File file = new File(filePath);
        if (file.exists()) {
            if (file.isDirectory()) {
                throw new IOException("File '" + file + "' exists but is a directory");
            }

            if (!file.canWrite()) {
                throw new IOException("File '" + file + "' cannot be written to");
            }
        } else {
            File parent = file.getParentFile();
            if (parent != null && !parent.exists() && !parent.mkdirs()) {
                throw new IOException("File '" + file + "' could not be created");
            }

            file.createNewFile();
        }

        return new FileOutputStream(file);
    }

    public static boolean removeFile(Context mContext, String file) {
        File f = new File(file);
        return f.exists() ? f.delete() : true;
    }

    /**
     * 解压assets的zip压缩文件到指定目录
     *
     * @param context   AppContext
     * @param assetName 预置文件名，asset下相对路径+文件名
     * @param destDir   目标目录，绝对路径
     * @param isReWrite 是否覆盖
     */
    public static void unzipFileFromAsset(Context context, String assetName, String destDir, boolean isReWrite) {
        if (null == context || TextUtils.isEmpty(assetName) || TextUtils.isEmpty(destDir)) {
            return;
        }
        // 创建解压目标目录
        File file = new File(destDir);
        // 如果目标目录不存在，则创建
        if (!file.exists()) {
            file.mkdirs();
        }

        InputStream inputStream = null;
        ZipInputStream zipInputStream = null;
        try {
            // 打开压缩文件
            inputStream = context.getAssets().open(assetName);

            zipInputStream = new ZipInputStream(inputStream);
            // 读取一个进入点
            ZipEntry zipEntry = zipInputStream.getNextEntry();

            byte[] buffer = new byte[1024];
            int count = 0;

            while (zipEntry != null) {
                // 如果是一个目录
                if (zipEntry.isDirectory()) {
                    file = new File(destDir + File.separator + zipEntry.getName());
                    // 文件需要覆盖或者是文件不存在
                    if (isReWrite || !file.exists()) {
                        file.mkdir();
                    }
                } else {
                    // 如果是文件
                    file = new File(destDir + File.separator + zipEntry.getName());
                    // 文件需要覆盖或者文件不存在，则解压文件
                    if (isReWrite || !file.exists()) {
                        file.createNewFile();
                        FileOutputStream fileOutputStream = null;
                        try {
                            fileOutputStream = new FileOutputStream(file);
                            while ((count = zipInputStream.read(buffer)) > 0) {
                                fileOutputStream.write(buffer, 0, count);
                            }
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            if (null != fileOutputStream) {
                                fileOutputStream.close();
                            }
                        }
                    }
                }
                // 定位到下一个文件入口
                zipEntry = zipInputStream.getNextEntry();
            }
            zipInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != inputStream) {
                    inputStream.close();
                }
                if (null != zipInputStream) {
                    zipInputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void unzipFile(File zipFile, String desDir) throws ZipException, IOException {
        unzipFile(zipFile, new File(desDir));
    }

    public static void unzipFile(File zipFile, File desDir) throws ZipException, IOException {
        if (!desDir.exists()) {
            desDir.mkdirs();
        }
        String folderPath = desDir.getAbsolutePath();

        ZipFile zf = new ZipFile(zipFile);
        Enumeration entries = zf.entries();

        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            String entryName = entry.getName();
            if ("./".equals(entryName)) {
                continue;
            } else if (".".equals(entryName)) {
                continue;
            } else if (entryName.endsWith("/")) {
                continue;
            }
            InputStream in = zf.getInputStream(entry);
//            entryName = new String(entryName.getBytes("8859_1"), "GB2312");
            String str = folderPath + File.separator + entryName;
            File desFile = new File(str);
            if (!desFile.exists()) {
                File fileParentDir = desFile.getParentFile();
                if (!fileParentDir.exists()) {
                    fileParentDir.mkdirs();
                }

                desFile.createNewFile();
            }

            OutputStream out = new FileOutputStream(desFile);
            byte[] buffer = new byte[10240];

            int realLength;
            while ((realLength = in.read(buffer)) > 0) {
                out.write(buffer, 0, realLength);
            }

            in.close();
            out.close();
        }

    }

    public static boolean checkFile(String filePath) {
        if (checkSD() == false || StringUtils.isNull(filePath)) {
            return false;
        }
        try {
            File file = new File(filePath);
            if (file.exists()) {
                return true;
            } else {
                return false;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    /**
     * 检查SD卡是否存在
     *
     * @return true：存在； false：不存在
     */
    public static boolean checkSD() {
        try {
            String status = Environment.getExternalStorageState();
            if (status.equals(Environment.MEDIA_MOUNTED)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * DuAr贴纸目录 v1.14.0 duar-v3.2
     */
    public static final String DIR_DU_STICKER = "duSticker";
    public static final String DIR_DU_MODEL = "duModel";
    public static final String DIR_DU_SO = "duSo";
    /**
     * Baidu ar 目录
     */
    public static final String DIR_DUAR = "duar";
    /**
     * ugc的文件目录
     */
    private static final String DIR_UGC_DEFAULT = "ugccapture";

    /**
     * 获取文件名，不包含后缀名
     *
     * @param fileName 文件名
     * @return
     */
    public static final String getPrefix(@NonNull String fileName) {
        return fileName.substring(0, fileName.lastIndexOf("."));
    }

    /**
     * 获取文件后缀
     *
     * @param fileName 文件名
     * @return
     */
    public static final String getSuffix(@NonNull String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    /**
     * 获取文件全名
     *
     * @param uri
     * @return
     */
    public static final String getFileFullName(String uri) {
        return uri.substring(uri.lastIndexOf("/") + 1, uri.length());
    }

    /**
     * 获取不带后缀的文件名
     *
     * @param uri
     * @return
     */
    public static final String getFileNameWithOutExtention(String uri) {
        return removeExtention(getFileFullName(uri));
    }

    /**
     * This method zips the directory
     *
     * @param dir
     * @param zipDirName
     */
    public static void zipDirectory(File dir, String zipDirName) {
        try {
            List<String> filesListInDir = new ArrayList<>();
            populateFilesList(dir, filesListInDir);
            // now zip files one by one
            // create ZipOutputStream to write to the zip file
            FileOutputStream fos = new FileOutputStream(zipDirName);
            ZipOutputStream zos = new ZipOutputStream(fos);
            for (String filePath : filesListInDir) {
                System.out.println("Zipping " + filePath);
                // for ZipEntry we need to keep only relative file path, so we used substring on absolute path
                ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length() + 1, filePath.length()));
                zos.putNextEntry(ze);
                // read the file and write to ZipOutputStream
                FileInputStream fis = new FileInputStream(filePath);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
                zos.closeEntry();
                fis.close();
            }
            zos.close();
            fos.close();
            filesListInDir.clear();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * This method populates all the files in a directory to a List
     *
     * @param dir
     * @throws IOException
     */
    private static void populateFilesList(File dir, List<String> filesListInDir) throws IOException {
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isFile()) {
                filesListInDir.add(file.getAbsolutePath());
            } else {
                populateFilesList(file, filesListInDir);
            }
        }
    }

    /**
     * This method compresses the single file to zip format
     *
     * @param file
     * @param zipFileName
     */
    public static void zipSingleFile(File file, String zipFileName) {
        try {
            // create ZipOutputStream to write to the zip file
            FileOutputStream fos = new FileOutputStream(zipFileName);
            ZipOutputStream zos = new ZipOutputStream(fos);
            // add a new Zip Entry to the ZipOutputStream
            ZipEntry ze = new ZipEntry(file.getName());
            zos.putNextEntry(ze);
            // read the file and write to ZipOutputStream
            FileInputStream fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }
            // Close the zip entry to write to zip file
            zos.closeEntry();
            // Close resources
            zos.close();
            fis.close();
            fos.close();
            System.out.println(file.getCanonicalPath() + " is zipped to " + zipFileName);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void close(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

    public static long getFileSize(File f) {
        long s = 0;
        FileInputStream fis = null;
        try {
            if (f.exists()) {
                fis = new FileInputStream(f);
                s = fis.available();
            }
        } catch (Exception ex) {
//            BdLog.e(ex);
            s = 0;
        } finally {
            BdCloseHelper.close(fis);
        }
        return s;
    }

    public static long getFileSize(String path) {
        try {
            if (TextUtils.isEmpty(path)) {
                return 0L;
            }
            File dir = new File(path);
            return dir.length();
        } catch (Exception e) {
            return 0L;
        }
    }


    public static String getParentDir(String filePath) {
        if (TextUtils.isEmpty(filePath) || !new File(filePath).exists()) {
            return "";
        }
        File parentDir = new File(filePath).getParentFile();
        if (parentDir == null) {
            return "";
        }
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }
        return parentDir.getAbsolutePath() + File.separator;
    }



    public static long calculateFileSize(String path) {
        File dir = new File(path);
        if (dir == null || !dir.exists()) {
            return 0;
        }
        return getSize(dir);
    }

    /**
     * 得到文件大小
     */
    public static long getSize(File file) {
        long size = 0;
        if (file == null || !file.exists()) {
            return 0;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files == null || files.length == 0) {
                return size;
            }
            final int count = files.length;
            for (int i = 0; i < count; i++) {
                size += getSize(files[i]);
            }
        } else {
            if (file != null) {
                size = file.length();
            }
        }
        return size;
    }

    /**
     * 保存bitmap到文件为JPG格式
     *
     * @param dir
     * @param filename
     * @param bm
     * @param quality
     * @return
     */
    public static String saveBitmap2JPG(String dir, String filename, Bitmap bm, int quality) {
        return saveBitmap(dir, filename, bm, quality, Bitmap.CompressFormat.JPEG);
    }

    /**
     * 保存bitmap到文件为PNG格式
     *
     * @param dir
     * @param filename
     * @param bm
     * @param quality
     * @return
     */
    public static String saveBitmap2PNG(String dir, String filename, Bitmap bm, int quality) {
        return saveBitmap(dir, filename, bm, quality, Bitmap.CompressFormat.PNG);
    }


    /**
     * 保存图片
     */
    public static String saveBitmap(String dir, String filename, Bitmap bm,
                                    int quality, Bitmap.CompressFormat format) {
        FileOutputStream outputStream = null;
        try {
            if (bm == null) {
                return null;
            }
            File dirFile = new File(dir);
            if (!dirFile.exists() && !dirFile.mkdirs()) {
                return null;
            }
            File file = new File(dir, filename);
            if (file.exists() && !file.delete()) {
                return null;
            }
            if (!file.createNewFile()) {
                return null;
            }
            outputStream = new FileOutputStream(file);
            bm.compress(format, quality, outputStream);
            return file.getAbsolutePath();
        } catch (IOException e) {
//            BdLog.e(e);
            return null;
        } finally {
            BdCloseHelper.close(outputStream);


        }
    }

    private static boolean doCopyFile(File srcFile, File destFile) throws IOException {
        if (destFile.exists() && destFile.isDirectory()) {
            return false;
        } else {
            FileInputStream fis = null;
            FileOutputStream fos = null;
            FileChannel input = null;
            FileChannel output = null;

            try {
                fis = new FileInputStream(srcFile);
                fos = new FileOutputStream(destFile);
                input = fis.getChannel();
                output = fos.getChannel();
                long size = input.size();
                long pos = 0L;

                for (long count = 0L; pos < size; pos += output.transferFrom(input, pos, count)) {
                    count = size - pos > 31457280L ? 31457280L : size - pos;
                }
                return true;
            } catch (Exception e) {
//                BdLog.e(e);
                return false;
            } finally {
                BdCloseHelper.close(output);
                BdCloseHelper.close(fos);
                BdCloseHelper.close(input);
                BdCloseHelper.close(fis);
            }
        }
    }


    /**
     * 写文件，可以指定写文件的模式覆盖还是追加
     *
     * @param file
     * @param content
     * @param append
     * @return
     */
    public static boolean writeFile(File file, String content, boolean append) {
        boolean success = false;
        FileOutputStream fos = null;
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            fos = new FileOutputStream(file, append);
            fos.write(content.getBytes());
            fos.flush();
            success = true;
        } catch (Exception e) { // IOException
            e.printStackTrace();
        } finally {
            BdCloseHelper.close(fos);
        }
        return success;
    }

    /**
     * 获取文件夹，如果不存在会创建
     *
     * @param dirName
     * @return
     */
    public static File getPrivateCaptureRootChildDir(String dirName) {
        File dir = new File(ContextConstant.getContext().getCacheDir(), dirName);
        if (!dir.exists()) {
            if (dir.mkdirs()) {
                return dir;
            } else {
                // 几乎不会走到这里，当外部存储 和 私有目录都无效时，才使用内部存储
                if (BuildConfig.DEBUG) {
                    throw new RuntimeException(new Throwable());
                }
                return ContextConstant.getContext().getCacheDir();
            }
        }
        return dir;
    }

    /**
     * 压缩文件列表到指定目录
     *
     * @param resFileList
     * @param zipFile
     * @param comment
     * @throws IOException
     */
    public static void zipFiles(Collection<File> resFileList, File zipFile, String comment)
            throws IOException {
        ZipOutputStream zipout =
                new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), 10240));
        Iterator var4 = resFileList.iterator();

        while (var4.hasNext()) {
            File resFile = (File) var4.next();
            zipFile(resFile, zipout, "");
        }

        zipout.setComment(comment);
        zipout.close();
    }

    private static void zipFile(File resFile, ZipOutputStream zipout, String rootpath) throws
            IOException {
        if (rootpath != null && rootpath.length() > 0) {
            rootpath = rootpath.trim();
            if (rootpath.length() > 0) {
                rootpath = rootpath + File.separator + resFile.getName();
            } else {
                rootpath = resFile.getName();
            }
        } else {
            rootpath = resFile.getName();
        }

        rootpath = new String(rootpath.getBytes("8859_1"), "GBK");
        int realLength;
        if (resFile.isDirectory()) {
            File[] fileList = resFile.listFiles();
            File[] var4 = fileList;
            realLength = fileList.length;

            for (int var6 = 0; var6 < realLength; ++var6) {
                File file = var4[var6];
                zipFile(file, zipout, rootpath);
            }
        } else {
            byte[] buffer = new byte[10240];
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(resFile), 10240);
            zipout.putNextEntry(new ZipEntry(rootpath));

            while ((realLength = in.read(buffer)) != -1) {
                zipout.write(buffer, 0, realLength);
            }

            in.close();
            zipout.flush();
            zipout.closeEntry();
        }

    }

    /**
     * 获取ugc 拍摄文件目录根目录
     *
     * @return /storage/sdcard0/Android/data/com.baidu.minivideo/files/ugccapture
     */
    public static File getBaiDuUgcCacheFile() {
        File rootDir = null;
        if (FileUtils.isSDMounted()) {
            rootDir = ContextConstant.getContext().getExternalFilesDir(null);
        }
        File dir = new File(rootDir, DIR_UGC_DEFAULT);

        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    /**
     * 去除文件后缀名
     *
     * @param filePath
     * @return
     */
    public static String removeExtention(String filePath) {
        // These first few lines the same as Justin's
        File f = new File(filePath);

        // if it's a directory, don't remove the extention
        if (f.isDirectory()) {
            return filePath;
        }

        String name = f.getName();

        // Now we know it's a file - don't need to do any special hidden
        // checking or contains() checking because of:
        final int lastPeriodPos = name.lastIndexOf('.');
        if (lastPeriodPos <= 0) {
            // No period after first character - return name as it was passed in
            return filePath;
        } else {
            // Remove the last period and everything after it
            File renamed = new File(f.getParent(), name.substring(0, lastPeriodPos));
            return renamed.getPath();
        }
    }

    /**
     * 判断文件是否存在，不存在则创建个
     *
     * @param path
     */
    public static boolean mkdirs(String path) {
        File dir = new File(path);
        if (!dir.exists()) {
            if (dir.mkdirs()) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 删除某个文件夹下所有文件，注意不支持删除子文件夹
     *
     * @param dir
     */
    public static void deleteAllFilesInDir(File dir) {
        if (dir == null) {
            return;
        }
        File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }

        for (File file : files) {
            if (!file.isDirectory()) {
                file.delete();
            }
        }
    }

    /**
     * 获取文件名后缀
     *
     * @param fileName 文件名
     * @return
     */
    public static String getFileExt(String fileName) {
        int pos = fileName.lastIndexOf(".");
        if (pos == -1) {
            return "";
        }
        return fileName.substring(pos + 1).toLowerCase();
    }
}
