content: /**
   * Copyright 2014 Zhenguo Jin
   * <p/>
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * <p/>
   * http://www.apache.org/licenses/LICENSE-2.0
   * <p/>
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.rsen.github.androidutils;
  
  import android.app.Activity;
  import android.content.CursorLoader;
  import android.content.Intent;
  import android.database.Cursor;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Environment;
  import android.provider.MediaStore;
  import android.text.TextUtils;
  
  import java.io.BufferedReader;
  import java.io.ByteArrayOutputStream;
  import java.io.File;
  import java.io.FileFilter;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStream;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  
  /**
   * 文件操作工具类
   * <p/>
   * <ul>
   * Read or write file
   * <li>{@link #readFile(String)} read file</li>
   * <li>{@link #readFileToList(String)} read file to string list</li>
   * <li>{@link #writeFile(String, String, boolean)} write file from String</li>
   * <li>{@link #writeFile(String, String)} write file from String</li>
   * <li>{@link #writeFile(String, List, boolean)} write file from String List</li>
   * <li>{@link #writeFile(String, List)} write file from String List</li>
   * <li>{@link #writeFile(String, InputStream)} write file</li>
   * <li>{@link #writeFile(String, InputStream, boolean)} write file</li>
   * <li>{@link #writeFile(File, InputStream)} write file</li>
   * <li>{@link #writeFile(File, InputStream, boolean)} write file</li>
   * </ul>
   * <ul>
   * Operate file
   * <li>{@link #copyFile(String, String)}</li>
   * <li>{@link #getFileExtension(String)}</li>
   * <li>{@link #getFileName(String)}</li>
   * <li>{@link #getFileNameWithoutExtension(String)}</li>
   * <li>{@link #getFileSize(String)}</li>
   * <li>{@link #deleteFile(String)}</li>
   * <li>{@link #isFileExist(String)}</li>
   * <li>{@link #isFolderExist(String)}</li>
   * <li>{@link #makeFolders(String)}</li>
   * <li>{@link #makeDirs(String)}</li>
   * </ul>
   *
   * @author jingle1267@163.com
   */
  public final class FileUtils {
  
      public static final long GB = 1073741824; // 1024 * 1024 * 1024
      public static final long MB = 1048576; // 1024 * 1024
      public static final long KB = 1024;
  
      public static final int ICON_TYPE_ROOT = 1;
      public static final int ICON_TYPE_FOLDER = 2;
      public static final int ICON_TYPE_MP3 = 3;
      public static final int ICON_TYPE_MTV = 4;
      public static final int ICON_TYPE_JPG = 5;
      public static final int ICON_TYPE_FILE = 6;
  
      public static final String MTV_REG = "^.*\\.(mp4|3gp)$";
      public static final String MP3_REG = "^.*\\.(mp3|wav)$";
      public static final String JPG_REG = "^.*\\.(gif|jpg|png)$";
  
      private static final String FILENAME_REGIX = "^[^\\/?\"*:<>\\]{1,255}$";
  
      /**
       * Don't let anyone instantiate this class.
       */
      private FileUtils() {
          throw new Error("Do not need instantiate!");
      }
  
      /**
       * 删除文件或者空的文件夹
       *
       * @param file File对象
       * @return 执行结果
       */
      public static boolean deleteFile(File file) {
  
          return file.delete();
      }
  
      /**
       * 递归删除文件和文件夹
       *
       * @param file 要删除的根目录
       * @return {@code true} if this file was deleted, {@code false} otherwise.
       */
      public static boolean DeleteFile(File file) {
          if (file == null || !file.exists()) {
              return false;
          }
          if (file.isFile()) {
              return file.delete();
          }
          if (!file.isDirectory()) {
              return false;
          }
          File[] childFile = file.listFiles();
          if (childFile == null || childFile.length == 0) {
              return file.delete();
          }
          for (File f : childFile) {
              DeleteFile(f);
          }
          return file.delete();
      }
  
      /**
       * 重命名文件和文件夹
       *
       * @param file        File对象
       * @param newFileName 新的文件名
       * @return 执行结果
       */
      public static boolean renameFile(File file, String newFileName) {
          if (newFileName.matches(FILENAME_REGIX)) {
              File newFile = null;
              if (file.isDirectory()) {
                  newFile = new File(file.getParentFile(), newFileName);
              } else {
                  String temp = newFileName
                          + file.getName().substring(
                          file.getName().lastIndexOf('.'));
                  newFile = new File(file.getParentFile(), temp);
              }
              if (file.renameTo(newFile)) {
                  return true;
              }
          }
          return false;
      }
  
      /**
       * 文件大小获取
       *
       * @param file File对象
       * @return 文件大小字符串
       */
      public static String getFileSize(File file) {
          FileInputStream fis = null;
          try {
              fis = new FileInputStream(file);
              int length = fis.available();
              if (length >= GB) {
                  return String.format("%.2f GB", length * 1.0 / GB);
              } else if (length >= MB) {
                  return String.format("%.2f MB", length * 1.0 / MB);
              } else {
                  return String.format("%.2f KB", length * 1.0 / KB);
              }
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              try {
                  fis.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          return "未知";
      }
  
      /**
       * 使用系统程序打开文件
       *
       * @param activity Activity
       * @param file     File
       * @throws Exception
       */
      public static void openFile(Activity activity, File file) throws Exception {
          Intent intent = new Intent();
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          intent.setAction(Intent.ACTION_VIEW);
          intent.setDataAndType(Uri.fromFile(file), getMimeType(file, activity));
          activity.startActivity(intent);
      }
  
      /**
       * 获取以后缀名为ID的值
       *
       * @param file     File
       * @param activity Activity
       * @return MimeType字符串
       * @throws Exception
       */
      public static String getMimeType(File file, Activity activity)
              throws Exception {
  
          String name = file.getName()
                  .substring(file.getName().lastIndexOf('.') + 1).toLowerCase();
          int id = activity.getResources().getIdentifier(
                  activity.getPackageName() + ":string/" + name, null, null);
  
          // 特殊处理
          if ("class".equals(name)) {
              return "application/octet-stream";
          }
          if ("3gp".equals(name)) {
              return "video/3gpp";
          }
          if ("nokia-op-logo".equals(name)) {
              return "image/vnd.nok-oplogo-color";
          }
          if (id == 0) {
              throw new Exception("未找到分享该格式的应用");
          }
          return activity.getString(id);
      }
  
      /**
       * 用于递归查找文件夹下面的符合条件的文件
       *
       * @param folder 文件夹
       * @param filter 文件过滤器
       * @return 符合条件的文件List
       */
      public static List<HashMap<String, Object>> recursionFolder(File folder,
                                                                  FileFilter filter) {
  
          List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
  
          // 获得文件夹下的所有目录和文件集合
          File[] files = folder.listFiles();
          /** 如果文件夹下没内容,会返回一个null **/
          // 判断适配器是否为空
          if (filter != null) {
              files = folder.listFiles(filter);
          }
          // 找到合适的文件返回
          if (files != null) {
              for (int m = 0; m < files.length; m++) {
                  File file = files[m];
                  if (file.isDirectory()) {
                      // 是否递归调用
                      list.addAll(recursionFolder(file, filter));
  
                  } else {
                      HashMap<String, Object> map = new HashMap<String, Object>();
                      map.put("file", file);
                      // 设置图标种类
                      if (file.getAbsolutePath().toLowerCase().matches(MP3_REG)) {
                          map.put("iconType", 3);
                      } else if (file.getAbsolutePath().toLowerCase()
                              .matches(MTV_REG)) {
                          map.put("iconType", 4);
                      } else if (file.getAbsolutePath().toLowerCase()
                              .matches(JPG_REG)) {
                          map.put("iconType", 5);
                      } else {
                          map.put("iconType", 6);
                      }
                      list.add(map);
                  }
              }
          }
          return list;
      }
  
      /**
       * 资源管理器,查找该文件夹下的文件和目录
       *
       * @param folder 文件夹
       * @param filter 文件过滤器
       * @return 符合条件的List
       */
      public static List<HashMap<String, Object>> unrecursionFolder(File folder,
                                                                    FileFilter filter) {
          List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
          // 如果是SD卡路径,不添加父路径
          if (!folder.getAbsolutePath().equals(
                  Environment.getExternalStorageDirectory().getAbsolutePath())) {
              HashMap<String, Object> map = new HashMap<String, Object>();
              map.put("file", folder.getParentFile());
              map.put("iconType", ICON_TYPE_ROOT);
              list.add(map);
          }
          // 获得文件夹下的所有目录和文件集合
          File[] files = folder.listFiles();
          /** 如果文件夹下没内容,会返回一个null **/
          // 判断适配器是否为空
          if (filter != null) {
              files = folder.listFiles(filter);
          }
          if (files != null && files.length > 0) {
              for (File p : files) {
                  HashMap<String, Object> map = new HashMap<String, Object>();
                  map.put("file", p);
                  // 设置图标种类
                  if (p.isDirectory()) {
                      map.put("iconType", ICON_TYPE_FOLDER);
                  } else {
                      if (p.getAbsolutePath().toLowerCase().matches(MP3_REG)) {
                          map.put("iconType", ICON_TYPE_MP3);
                      } else if (p.getAbsolutePath().toLowerCase()
                              .matches(MTV_REG)) {
                          map.put("iconType", ICON_TYPE_MTV);
                      } else if (p.getAbsolutePath().toLowerCase()
                              .matches(JPG_REG)) {
                          map.put("iconType", ICON_TYPE_JPG);
                      } else {
                          map.put("iconType", ICON_TYPE_FILE);
                      }
                  }
                  // 添加
                  list.add(map);
              }
          }
          return list;
      }
  
      /**
       * 示例:"^.*\\.(mp3|mp4|3gp)$"
       *
       * @param reg 目前允许取值 REG_MTV, REG_MP3, REG_JPG三种
       * @return 文件过滤器
       */
      public static FileFilter getFileFilter(final String reg, boolean isdir) {
          if (isdir) {
              return new FileFilter() {
                  @Override
                  public boolean accept(File pathname) {
  
                      return pathname.getAbsolutePath().toLowerCase()
                              .matches(reg)
                              || pathname.isDirectory();
                  }
              };
          } else {
              return new FileFilter() {
                  @Override
                  public boolean accept(File pathname) {
  
                      return pathname.getAbsolutePath().toLowerCase()
                              .matches(reg)
                              && pathname.isFile();
                  }
              };
          }
      }
  
      public final static String FILE_EXTENSION_SEPARATOR = "";
  
      /**
       * read file
       *
       * @param filePath    文件路径
       * @param charsetName The name of a supported {@link java.nio.charset.Charset
       *                    </code>charset<code>}
       * @return if file not exist, return null, else return content of file
       * @throws RuntimeException if an error occurs while operator BufferedReader
       */
      public static StringBuilder readFile(String filePath, String charsetName) {
          File file = new File(filePath);
          StringBuilder fileContent = new StringBuilder("");
          if (!file.isFile()) {
              return null;
          }
  
          BufferedReader reader = null;
          try {
              InputStreamReader is = new InputStreamReader(new FileInputStream(
                      file), charsetName);
              reader = new BufferedReader(is);
              String line;
              while ((line = reader.readLine()) != null) {
                  if (!fileContent.toString().equals("")) {
                      fileContent.append("\r\n");
                  }
                  fileContent.append(line);
              }
              reader.close();
              return fileContent;
          } catch (IOException e) {
              throw new RuntimeException("IOException occurred. ", e);
          } finally {
              if (reader != null) {
                  try {
                      reader.close();
                  } catch (IOException e) {
                      throw new RuntimeException("IOException occurred. ", e);
                  }
              }
          }
      }
  
      /**
       * write file
       *
       * @param filePath 文件路径
       * @param content  内容
       * @param append   is append, if true, write to the end of file, else clear
       *                 content of file and write into it
       * @return return false if content is empty, true otherwise
       * @throws RuntimeException if an error occurs while operator FileWriter
       */
      public static boolean writeFile(String filePath, String content,
                                      boolean append) {
          if (TextUtils.isEmpty(content)) {
              return false;
          }
  
          FileWriter fileWriter = null;
          try {
              makeDirs(filePath);
              fileWriter = new FileWriter(filePath, append);
              fileWriter.write(content);
              fileWriter.close();
              return true;
          } catch (IOException e) {
              throw new RuntimeException("IOException occurred. ", e);
          } finally {
              if (fileWriter != null) {
                  try {
                      fileWriter.close();
                  } catch (IOException e) {
                      throw new RuntimeException("IOException occurred. ", e);
                  }
              }
          }
      }
  
      /**
       * write file
       *
       * @param filePath    文件路径
       * @param contentList 内容List
       * @param append      is append, if true, write to the end of file, else clear
       *                    content of file and write into it
       * @return return false if contentList is empty, true otherwise
       * @throws RuntimeException if an error occurs while operator FileWriter
       */
      public static boolean writeFile(String filePath, List<String> contentList,
                                      boolean append) {
          if (contentList == null || contentList.size() < 1) {
              return false;
          }
  
          FileWriter fileWriter = null;
          try {
              makeDirs(filePath);
              fileWriter = new FileWriter(filePath, append);
              int i = 0;
              for (String line : contentList) {
                  if (i++ > 0) {
                      fileWriter.write("\r\n");
                  }
                  fileWriter.write(line);
              }
              fileWriter.close();
              return true;
          } catch (IOException e) {
              throw new RuntimeException("IOException occurred. ", e);
          } finally {
              if (fileWriter != null) {
                  try {
                      fileWriter.close();
                  } catch (IOException e) {
                      throw new RuntimeException("IOException occurred. ", e);
                  }
              }
          }
      }
  
      /**
       * write file, the string will be written to the begin of the file
       *
       * @param filePath 文件路径
       * @param content  内容
       * @return 执行结果
       */
      public static boolean writeFile(String filePath, String content) {
          return writeFile(filePath, content, false);
      }
  
      /**
       * write file, the string list will be written to the begin of the file
       *
       * @param filePath    文件路径
       * @param contentList 内容List
       * @return 执行结果
       */
      public static boolean writeFile(String filePath, List<String> contentList) {
          return writeFile(filePath, contentList, false);
      }
  
      /**
       * write file, the bytes will be written to the begin of the file
       *
       * @param filePath 文件路径
       * @param stream   InputStream
       * @return 执行结果
       * @see {@link #writeFile(String, InputStream, boolean)}
       */
      public static boolean writeFile(String filePath, InputStream stream) {
          return writeFile(filePath, stream, false);
      }
  
      /**
       * write file
       *
       * @param filePath the file to be opened for writing.
       * @param stream   the input stream
       * @param append   if <code>true</code>, then bytes will be written to the end of
       *                 the file rather than the beginning
       * @return return true
       * @throws RuntimeException if an error occurs while operator FileOutputStream
       */
      public static boolean writeFile(String filePath, InputStream stream,
                                      boolean append) {
          return writeFile(filePath != null ? new File(filePath) : null, stream,
                  append);
      }
  
      /**
       * write file, the bytes will be written to the begin of the file
       *
       * @param file   File对象
       * @param stream InputStream
       * @return
       * @see {@link #writeFile(File, InputStream, boolean)}
       */
      public static boolean writeFile(File file, InputStream stream) {
          return writeFile(file, stream, false);
      }
  
      /**
       * write file
       *
       * @param file   the file to be opened for writing.
       * @param stream the input stream
       * @param append if <code>true</code>, then bytes will be written to the end of
       *               the file rather than the beginning
       * @return return true
       * @throws RuntimeException if an error occurs while operator FileOutputStream
       */
      public static boolean writeFile(File file, InputStream stream,
                                      boolean append) {
          OutputStream o = null;
          try {
              makeDirs(file.getAbsolutePath());
              o = new FileOutputStream(file, append);
              byte data[] = new byte[1024];
              int length = -1;
              while ((length = stream.read(data)) != -1) {
                  o.write(data, 0, length);
              }
              o.flush();
              return true;
          } catch (FileNotFoundException e) {
              throw new RuntimeException("FileNotFoundException occurred. ", e);
          } catch (IOException e) {
              throw new RuntimeException("IOException occurred. ", e);
          } finally {
              if (o != null) {
                  try {
                      o.close();
                      stream.close();
                  } catch (IOException e) {
                      throw new RuntimeException("IOException occurred. ", e);
                  }
              }
          }
      }
  
      /**
       * copy file
       *
       * @param sourceFilePath 源文件路径
       * @param destFilePath   目标文件路径
       * @return 执行结果
       * @throws RuntimeException if an error occurs while operator FileOutputStream
       */
      public static boolean copyFile(String sourceFilePath, String destFilePath) {
          InputStream inputStream = null;
          try {
              inputStream = new FileInputStream(sourceFilePath);
          } catch (FileNotFoundException e) {
              throw new RuntimeException("FileNotFoundException occurred. ", e);
          }
          return writeFile(destFilePath, inputStream);
      }
  
      /**
       * 输入流转byte[]
       *
       * @param inStream InputStream
       * @return Byte数组
       */
      public static final byte[] input2byte(InputStream inStream) {
          if (inStream == null)
              return null;
          ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
          byte[] buff = new byte[100];
          int rc = 0;
          try {
              while ((rc = inStream.read(buff, 0, 100)) > 0) {
                  swapStream.write(buff, 0, rc);
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
          return swapStream.toByteArray();
      }
  
      /**
       * read file to string list, a element of list is a line
       *
       * @param filePath    文件路径
       * @param charsetName 编码方式
       *                    The name of a supported {@link java.nio.charset.Charset
       *                    </code>charset<code>}
       * @return if file not exist, return null, else return content of file
       * @throws RuntimeException if an error occurs while operator BufferedReader
       */
      public static List<String> readFileToList(String filePath,
                                                String charsetName) {
          File file = new File(filePath);
          List<String> fileContent = new ArrayList<String>();
          if (!file.isFile()) {
              return null;
          }
  
          BufferedReader reader = null;
          try {
              InputStreamReader is = new InputStreamReader(new FileInputStream(
                      file), charsetName);
              reader = new BufferedReader(is);
              String line = null;
              while ((line = reader.readLine()) != null) {
                  fileContent.add(line);
              }
              reader.close();
              return fileContent;
          } catch (IOException e) {
              throw new RuntimeException("IOException occurred. ", e);
          } finally {
              if (reader != null) {
                  try {
                      reader.close();
                  } catch (IOException e) {
                      throw new RuntimeException("IOException occurred. ", e);
                  }
              }
          }
      }
  
      /**
       * get file name from path, not include suffix
       * <p/>
       * <pre>
       *      getFileNameWithoutExtension(null)               =   null
       *      getFileNameWithoutExtension("")                 =   ""
       *      getFileNameWithoutExtension("   ")              =   "   "
       *      getFileNameWithoutExtension("abc")              =   "abc"
       *      getFileNameWithoutExtension("a.mp3")            =   "a"
       *      getFileNameWithoutExtension("a.b.rmvb")         =   "a.b"
       *      getFileNameWithoutExtension("c:\\")              =   ""
       *      getFileNameWithoutExtension("c:\\a")             =   "a"
       *      getFileNameWithoutExtension("c:\\a.b")           =   "a"
       *      getFileNameWithoutExtension("c:a.txt\\a")        =   "a"
       *      getFileNameWithoutExtension("/home/admin")      =   "admin"
       *      getFileNameWithoutExtension("/home/admin/a.txt/b.mp3")  =   "b"
       * </pre>
       *
       * @param filePath 文件路径
       * @return file name from path, not include suffix
       * @see
       */
      public static String getFileNameWithoutExtension(String filePath) {
          if (TextUtils.isEmpty(filePath)) {
              return filePath;
          }
  
          int extenPosi = filePath.lastIndexOf(FILE_EXTENSION_SEPARATOR);
          int filePosi = filePath.lastIndexOf(File.separator);
          if (filePosi == -1) {
              return (extenPosi == -1 ? filePath : filePath.substring(0,
                      extenPosi));
          }
          if (extenPosi == -1) {
              return filePath.substring(filePosi + 1);
          }
          return (filePosi < extenPosi ? filePath.substring(filePosi + 1,
                  extenPosi) : filePath.substring(filePosi + 1));
      }
  
      /**
       * get file name from path, include suffix
       * <p/>
       * <pre>
       *      getFileName(null)               =   null
       *      getFileName("")                 =   ""
       *      getFileName("   ")              =   "   "
       *      getFileName("a.mp3")            =   "a.mp3"
       *      getFileName("a.b.rmvb")         =   "a.b.rmvb"
       *      getFileName("abc")              =   "abc"
       *      getFileName("c:\\")              =   ""
       *      getFileName("c:\\a")             =   "a"
       *      getFileName("c:\\a.b")           =   "a.b"
       *      getFileName("c:a.txt\\a")        =   "a"
       *      getFileName("/home/admin")      =   "admin"
       *      getFileName("/home/admin/a.txt/b.mp3")  =   "b.mp3"
       * </pre>
       *
       * @param filePath 文件路径
       * @return file name from path, include suffix
       */
      public static String getFileName(String filePath) {
          if (TextUtils.isEmpty(filePath)) {
              return filePath;
          }
  
          int filePosi = filePath.lastIndexOf(File.separator);
          return (filePosi == -1) ? filePath : filePath.substring(filePosi + 1);
      }
  
      /**
       * get folder name from path
       * <p/>
       * <pre>
       *      getFolderName(null)               =   null
       *      getFolderName("")                 =   ""
       *      getFolderName("   ")              =   ""
       *      getFolderName("a.mp3")            =   ""
       *      getFolderName("a.b.rmvb")         =   ""
       *      getFolderName("abc")              =   ""
       *      getFolderName("c:\\")              =   "c:"
       *      getFolderName("c:\\a")             =   "c:"
       *      getFolderName("c:\\a.b")           =   "c:"
       *      getFolderName("c:a.txt\\a")        =   "c:a.txt"
       *      getFolderName("c:a\\b\\c\\d.txt")    =   "c:a\\b\\c"
       *      getFolderName("/home/admin")      =   "/home"
       *      getFolderName("/home/admin/a.txt/b.mp3")  =   "/home/admin/a.txt"
       * </pre>
       *
       * @param filePath 文件路径
       * @return 文件夹名称
       */
      public static String getFolderName(String filePath) {
  
          if (TextUtils.isEmpty(filePath)) {
              return filePath;
          }
  
          int filePosi = filePath.lastIndexOf(File.separator);
          return (filePosi == -1) ? "" : filePath.substring(0, filePosi);
      }
  
      /**
       * get suffix of file from path
       * <p/>
       * <pre>
       *      getFileExtension(null)               =   ""
       *      getFileExtension("")                 =   ""
       *      getFileExtension("   ")              =   "   "
       *      getFileExtension("a.mp3")            =   "mp3"
       *      getFileExtension("a.b.rmvb")         =   "rmvb"
       *      getFileExtension("abc")              =   ""
       *      getFileExtension("c:\\")              =   ""
       *      getFileExtension("c:\\a")             =   ""
       *      getFileExtension("c:\\a.b")           =   "b"
       *      getFileExtension("c:a.txt\\a")        =   ""
       *      getFileExtension("/home/admin")      =   ""
       *      getFileExtension("/home/admin/a.txt/b")  =   ""
       *      getFileExtension("/home/admin/a.txt/b.mp3")  =   "mp3"
       * </pre>
       *
       * @param filePath 文件路径
       * @return
       */
      public static String getFileExtension(String filePath) {
          if (TextUtils.isEmpty(filePath)) {
              return filePath;
          }
  
          int extenPosi = filePath.lastIndexOf(FILE_EXTENSION_SEPARATOR);
          int filePosi = filePath.lastIndexOf(File.separator);
          if (extenPosi == -1) {
              return "";
          }
          return (filePosi >= extenPosi) ? "" : filePath.substring(extenPosi + 1);
      }
  
      /**
       * Creates the directory named by the trailing filename of this file,
       * including the complete directory path required to create this directory. <br/>
       * <br/>
       * <ul>
       * <strong>Attentions:</strong>
       * <li>makeDirs("C:\\Users\\Trinea") can only create users folder</li>
       * <li>makeFolder("C:\\Users\\Trinea\\") can create Trinea folder</li>
       * </ul>
       *
       * @param filePath 文件路径
       * @return true if the necessary directories have been created or the target
       * directory already exists, false one of the directories can not be
       * created.
       * <ul>
       * <li>if {@link FileUtils#getFolderName(String)} return null,
       * return false</li>
       * <li>if target directory already exists, return true</li>
       * <li>return {@link File#makeFolder}</li>
       * </ul>
       */
      public static boolean makeDirs(String filePath) {
          String folderName = getFolderName(filePath);
          if (TextUtils.isEmpty(folderName)) {
              return false;
          }
  
          File folder = new File(folderName);
          return (folder.exists() && folder.isDirectory()) || folder
                  .mkdirs();
      }
  
      /**
       * @param filePath 文件路径
       * @return 执行结果
       * @see #makeDirs(String)
       */
      public static boolean makeFolders(String filePath) {
          return makeDirs(filePath);
      }
  
      /**
       * Indicates if this file represents a file on the underlying file system.
       *
       * @param filePath 文件路径
       * @return 是否存在文件
       */
      public static boolean isFileExist(String filePath) {
          if (TextUtils.isEmpty(filePath)) {
              return false;
          }
  
          File file = new File(filePath);
          return (file.exists() && file.isFile());
      }
  
      /**
       * Indicates if this file represents a directory on the underlying file
       * system.
       *
       * @param directoryPath 文件夹路径
       * @return 文件夹是否存在
       */
      public static boolean isFolderExist(String directoryPath) {
          if (TextUtils.isEmpty(directoryPath)) {
              return false;
          }
  
          File dire = new File(directoryPath);
          return (dire.exists() && dire.isDirectory());
      }
  
      /**
       * delete file or directory
       * <ul>
       * <li>if path is null or empty, return true</li>
       * <li>if path not exist, return true</li>
       * <li>if path exist, delete recursion. return true</li>
       * <ul>
       *
       * @param path 文件路径
       * @return 是否删除成功
       */
      public static boolean deleteFile(String path) {
          if (TextUtils.isEmpty(path)) {
              return true;
          }
  
          File file = new File(path);
          if (!file.exists()) {
              return true;
          }
          if (file.isFile()) {
              return file.delete();
          }
          if (!file.isDirectory()) {
              return false;
          }
          for (File f : file.listFiles()) {
              if (f.isFile()) {
                  f.delete();
              } else if (f.isDirectory()) {
                  deleteFile(f.getAbsolutePath());
              }
          }
          return file.delete();
      }
  
      /**
       * get file size
       * <ul>
       * <li>if path is null or empty, return -1</li>
       * <li>if path exist and it is a file, return file size, else return -1</li>
       * <ul>
       *
       * @param path 文件路径
       * @return returns the length of this file in bytes. returns -1 if the file
       * does not exist.
       */
      public static long getFileSize(String path) {
          if (TextUtils.isEmpty(path)) {
              return -1;
          }
  
          File file = new File(path);
          return (file.exists() && file.isFile() ? file.length() : -1);
      }
  
      /**
       * 把uri转为File对象
       *
       * @param activity Activity
       * @param uri      文件Uri
       * @return File对象
       */
      public static File uri2File(Activity activity, Uri uri) {
          if (Build.VERSION.SDK_INT < 11) {
              // 在API11以下可以使用：managedQuery
              String[] proj = {MediaStore.Images.Media.DATA};
              @SuppressWarnings("deprecation")
              Cursor actualimagecursor = activity.managedQuery(uri, proj, null, null,
                      null);
              int actual_image_column_index = actualimagecursor
                      .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
              actualimagecursor.moveToFirst();
              String img_path = actualimagecursor
                      .getString(actual_image_column_index);
              return new File(img_path);
          } else {
              // 在API11以上：要转为使用CursorLoader,并使用loadInBackground来返回
              String[] projection = {MediaStore.Images.Media.DATA};
              CursorLoader loader = new CursorLoader(activity, uri, projection, null,
                      null, null);
              Cursor cursor = loader.loadInBackground();
              int column_index = cursor
                      .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
              cursor.moveToFirst();
              return new File(cursor.getString(column_index));
          }
      }
  
  }
  