package com.qunar.im.ui.view.bigimageview.tool.utility.file; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.text.TextUtils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; 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.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; public final class FileUtil { public static final String[][] MIME_MapTable = { //{后缀名, MIME类型} { ".3gp", "video/3gpp" }, { ".apk", "application/vnd.android.package-archive" }, { ".asf", "video/x-ms-asf" }, { ".avi", "video/x-msvideo" }, { ".bin", "application/octet-stream" }, { ".bmp", "image/bmp" }, { ".c", "text/plain" }, { ".class", "application/octet-stream" }, { ".conf", "text/plain" }, { ".cpp", "text/plain" }, { ".doc", "application/msword" }, { ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, { ".xls", "application/vnd.ms-excel" }, { ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, { ".exe", "application/octet-stream" }, { ".gif", "image/gif" }, { ".gtar", "application/x-gtar" }, { ".gz", "application/x-gzip" }, { ".h", "text/plain" }, { ".htm", "text/html" }, { ".html", "text/html" }, { ".jar", "application/java-archive" }, { ".java", "text/plain" }, { ".jpeg", "image/jpeg" }, { ".jpg", "image/jpeg" }, { ".js", "application/x-javascript" }, { ".log", "text/plain" }, { ".m3u", "audio/x-mpegurl" }, { ".m4a", "audio/mp4a-latm" }, { ".m4b", "audio/mp4a-latm" }, { ".m4p", "audio/mp4a-latm" }, { ".m4u", "video/vnd.mpegurl" }, { ".m4v", "video/x-m4v" }, { ".mov", "video/quicktime" }, { ".mp2", "audio/x-mpeg" }, { ".mp3", "audio/x-mpeg" }, { ".mp4", "video/mp4" }, { ".mpc", "application/vnd.mpohun.certificate" }, { ".mpe", "video/mpeg" }, { ".mpeg", "video/mpeg" }, { ".mpg", "video/mpeg" }, { ".mpg4", "video/mp4" }, { ".mpga", "audio/mpeg" }, { ".msg", "application/vnd.ms-outlook" }, { ".ogg", "audio/ogg" }, { ".pdf", "application/pdf" }, { ".png", "image/png" }, { ".pps", "application/vnd.ms-powerpoint" }, { ".ppt", "application/vnd.ms-powerpoint" }, { ".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, { ".prop", "text/plain" }, { ".rc", "text/plain" }, { ".rmvb", "audio/x-pn-realaudio" }, { ".rtf", "application/rtf" }, { ".sh", "text/plain" }, { ".tar", "application/x-tar" }, { ".tgz", "application/x-compressed" }, { ".txt", "text/plain" }, { ".wav", "audio/x-wav" }, { ".wma", "audio/x-ms-wma" }, { ".wmv", "audio/x-ms-wmv" }, { ".wps", "application/vnd.ms-works" }, { ".xml", "text/plain" }, { ".z", "application/x-compress" }, { ".zip", "application/x-zip-compressed" }, { "", "*/*" } }; private static final String LINE_SEP = System.getProperty("line.separator"); private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static int sBufferSize = 8192; public FileUtil() { throw new UnsupportedOperationException("u can't instantiate me..."); } /** * Write file from input stream. * * @param filePath The path of file. * @param is The input stream. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromIS(final String filePath, final InputStream is) { return writeFileFromIS(getFileByPath(filePath), is, false); } /** * Write file from input stream. * * @param filePath The path of file. * @param is The input stream. * @param append True to append, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromIS(final String filePath, final InputStream is, final boolean append) { return writeFileFromIS(getFileByPath(filePath), is, append); } /** * Write file from input stream. * * @param file The file. * @param is The input stream. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromIS(final File file, final InputStream is) { return writeFileFromIS(file, is, false); } /** * Write file from input stream. * * @param file The file. * @param is The input stream. * @param append True to append, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromIS(final File file, final InputStream is, final boolean append) { if (!createOrExistsFile(file) || is == null) return false; OutputStream os = null; try { os = new BufferedOutputStream(new FileOutputStream(file, append)); byte data[] = new byte[sBufferSize]; int len; while ((len = is.read(data, 0, sBufferSize)) != -1) { os.write(data, 0, len); } return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } try { if (os != null) { os.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Write file from bytes by stream. * * @param filePath The path of file. * @param bytes The bytes. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByStream(final String filePath, final byte[] bytes) { return writeFileFromBytesByStream(getFileByPath(filePath), bytes, false); } /** * Write file from bytes by stream. * * @param filePath The path of file. * @param bytes The bytes. * @param append True to append, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByStream(final String filePath, final byte[] bytes, final boolean append) { return writeFileFromBytesByStream(getFileByPath(filePath), bytes, append); } /** * Write file from bytes by stream. * * @param file The file. * @param bytes The bytes. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByStream(final File file, final byte[] bytes) { return writeFileFromBytesByStream(file, bytes, false); } /** * Write file from bytes by stream. * * @param file The file. * @param bytes The bytes. * @param append True to append, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByStream(final File file, final byte[] bytes, final boolean append) { if (bytes == null || !createOrExistsFile(file)) return false; BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(file, append)); bos.write(bytes); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { if (bos != null) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Write file from bytes by channel. * * @param filePath The path of file. * @param bytes The bytes. * @param isForce 是否写入文件 * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByChannel(final String filePath, final byte[] bytes, final boolean isForce) { return writeFileFromBytesByChannel(getFileByPath(filePath), bytes, false, isForce); } /** * Write file from bytes by channel. * * @param filePath The path of file. * @param bytes The bytes. * @param append True to append, false otherwise. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByChannel(final String filePath, final byte[] bytes, final boolean append, final boolean isForce) { return writeFileFromBytesByChannel(getFileByPath(filePath), bytes, append, isForce); } /** * Write file from bytes by channel. * * @param file The file. * @param bytes The bytes. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByChannel(final File file, final byte[] bytes, final boolean isForce) { return writeFileFromBytesByChannel(file, bytes, false, isForce); } /** * Write file from bytes by channel. * * @param file The file. * @param bytes The bytes. * @param append True to append, false otherwise. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByChannel(final File file, final byte[] bytes, final boolean append, final boolean isForce) { if (bytes == null) return false; FileChannel fc = null; try { fc = new FileOutputStream(file, append).getChannel(); fc.position(fc.size()); fc.write(ByteBuffer.wrap(bytes)); if (isForce) fc.force(true); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { if (fc != null) { fc.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Write file from bytes by map. * * @param filePath The path of file. * @param bytes The bytes. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByMap(final String filePath, final byte[] bytes, final boolean isForce) { return writeFileFromBytesByMap(filePath, bytes, false, isForce); } /** * Write file from bytes by map. * * @param filePath The path of file. * @param bytes The bytes. * @param append True to append, false otherwise. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByMap(final String filePath, final byte[] bytes, final boolean append, final boolean isForce) { return writeFileFromBytesByMap(getFileByPath(filePath), bytes, append, isForce); } /** * Write file from bytes by map. * * @param file The file. * @param bytes The bytes. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByMap(final File file, final byte[] bytes, final boolean isForce) { return writeFileFromBytesByMap(file, bytes, false, isForce); } /** * Write file from bytes by map. * * @param file The file. * @param bytes The bytes. * @param append True to append, false otherwise. * @param isForce True to force write file, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromBytesByMap(final File file, final byte[] bytes, final boolean append, final boolean isForce) { if (bytes == null || !createOrExistsFile(file)) return false; FileChannel fc = null; try { fc = new FileOutputStream(file, append).getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, fc.size(), bytes.length); mbb.put(bytes); if (isForce) mbb.force(); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { if (fc != null) { fc.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Write file from string. * * @param filePath The path of file. * @param content The string of content. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromString(final String filePath, final String content) { return writeFileFromString(getFileByPath(filePath), content, false); } /** * Write file from string. * * @param filePath The path of file. * @param content The string of content. * @param append True to append, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromString(final String filePath, final String content, final boolean append) { return writeFileFromString(getFileByPath(filePath), content, append); } /////////////////////////////////////////////////////////////////////////// // the divide line of write and read /////////////////////////////////////////////////////////////////////////// /** * Write file from string. * * @param file The file. * @param content The string of content. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromString(final File file, final String content) { return writeFileFromString(file, content, false); } /** * Write file from string. * * @param file The file. * @param content The string of content. * @param append True to append, false otherwise. * @return {@code true}: success<br>{@code false}: fail */ public static boolean writeFileFromString(final File file, final String content, final boolean append) { if (file == null || content == null) return false; if (!createOrExistsFile(file)) return false; BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter(file, append)); bw.write(content); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { if (bw != null) { bw.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Return the lines in file. * * @param filePath The path of file. * @return the lines in file */ public static List<String> readFile2List(final String filePath) { return readFile2List(getFileByPath(filePath), null); } /** * Return the lines in file. * * @param filePath The path of file. * @param charsetName The name of charset. * @return the lines in file */ public static List<String> readFile2List(final String filePath, final String charsetName) { return readFile2List(getFileByPath(filePath), charsetName); } /** * Return the lines in file. * * @param file The file. * @return the lines in file */ public static List<String> readFile2List(final File file) { return readFile2List(file, 0, 0x7FFFFFFF, null); } /** * Return the lines in file. * * @param file The file. * @param charsetName The name of charset. * @return the lines in file */ public static List<String> readFile2List(final File file, final String charsetName) { return readFile2List(file, 0, 0x7FFFFFFF, charsetName); } /** * Return the lines in file. * * @param filePath The path of file. * @param st The line's index of start. * @param end The line's index of end. * @return the lines in file */ public static List<String> readFile2List(final String filePath, final int st, final int end) { return readFile2List(getFileByPath(filePath), st, end, null); } /** * Return the lines in file. * * @param filePath The path of file. * @param st The line's index of start. * @param end The line's index of end. * @param charsetName The name of charset. * @return the lines in file */ public static List<String> readFile2List(final String filePath, final int st, final int end, final String charsetName) { return readFile2List(getFileByPath(filePath), st, end, charsetName); } /** * Return the lines in file. * * @param file The file. * @param st The line's index of start. * @param end The line's index of end. * @return the lines in file */ public static List<String> readFile2List(final File file, final int st, final int end) { return readFile2List(file, st, end, null); } /** * Return the lines in file. * * @param file The file. * @param st The line's index of start. * @param end The line's index of end. * @param charsetName The name of charset. * @return the lines in file */ public static List<String> readFile2List(final File file, final int st, final int end, final String charsetName) { if (!isFileExists(file)) return null; if (st > end) return null; BufferedReader reader = null; try { String line; int curLine = 1; List<String> list = new ArrayList<>(); if (isSpace(charsetName)) { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); } else { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName)); } while ((line = reader.readLine()) != null) { if (curLine > end) break; if (st <= curLine && curLine <= end) list.add(line); ++curLine; } return list; } catch (IOException e) { e.printStackTrace(); return null; } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Return the string in file. * * @param filePath The path of file. * @return the string in file */ public static String readFile2String(final String filePath) { return readFile2String(getFileByPath(filePath), null); } /** * Return the string in file. * * @param filePath The path of file. * @param charsetName The name of charset. * @return the string in file */ public static String readFile2String(final String filePath, final String charsetName) { return readFile2String(getFileByPath(filePath), charsetName); } /** * Return the string in file. * * @param file The file. * @return the string in file */ public static String readFile2String(final File file) { return readFile2String(file, null); } /** * Return the string in file. * * @param file The file. * @param charsetName The name of charset. * @return the string in file */ public static String readFile2String(final File file, final String charsetName) { byte[] bytes = readFile2BytesByStream(file); if (bytes == null) return null; if (isSpace(charsetName)) { return new String(bytes); } else { try { return new String(bytes, charsetName); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return ""; } } } /** * Return the bytes in file by stream. * * @param filePath The path of file. * @return the bytes in file */ public static byte[] readFile2BytesByStream(final String filePath) { return readFile2BytesByStream(getFileByPath(filePath)); } /** * Return the bytes in file by stream. * * @param file The file. * @return the bytes in file */ public static byte[] readFile2BytesByStream(final File file) { if (!isFileExists(file)) return null; try { return is2Bytes(new FileInputStream(file)); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } } /** * Return the bytes in file by channel. * * @param filePath The path of file. * @return the bytes in file */ public static byte[] readFile2BytesByChannel(final String filePath) { return readFile2BytesByChannel(getFileByPath(filePath)); } /** * Return the bytes in file by channel. * * @param file The file. * @return the bytes in file */ public static byte[] readFile2BytesByChannel(final File file) { if (!isFileExists(file)) return null; FileChannel fc = null; try { fc = new RandomAccessFile(file, "r").getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate((int) fc.size()); while (true) { if (!((fc.read(byteBuffer)) > 0)) break; } return byteBuffer.array(); } catch (IOException e) { e.printStackTrace(); return null; } finally { try { if (fc != null) { fc.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Return the bytes in file by map. * * @param filePath The path of file. * @return the bytes in file */ public static byte[] readFile2BytesByMap(final String filePath) { return readFile2BytesByMap(getFileByPath(filePath)); } /** * Return the bytes in file by map. * * @param file The file. * @return the bytes in file */ public static byte[] readFile2BytesByMap(final File file) { if (!isFileExists(file)) return null; FileChannel fc = null; try { fc = new RandomAccessFile(file, "r").getChannel(); int size = (int) fc.size(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, size).load(); byte[] result = new byte[size]; mbb.get(result, 0, size); return result; } catch (IOException e) { e.printStackTrace(); return null; } finally { try { if (fc != null) { fc.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Set the buffer's size. * <p>Default size equals 8192 bytes.</p> * * @param bufferSize The buffer's size. */ public static void setBufferSize(final int bufferSize) { sBufferSize = bufferSize; } private static byte[] is2Bytes(final InputStream is) { if (is == null) return null; ByteArrayOutputStream os = null; try { os = new ByteArrayOutputStream(); byte[] b = new byte[sBufferSize]; int len; while ((len = is.read(b, 0, sBufferSize)) != -1) { os.write(b, 0, len); } return os.toByteArray(); } catch (IOException e) { e.printStackTrace(); return null; } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } try { if (os != null) { os.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Return the file by path. * * @param filePath The path of file. * @return the file */ public static File getFileByPath(final String filePath) { return isSpace(filePath) ? null : new File(filePath); } /** * Return whether the file exists. * * @param filePath The path of file. * @return {@code true}: yes<br>{@code false}: no */ public static boolean isFileExists(final String filePath) { return isFileExists(getFileByPath(filePath)); } /** * Return whether the file exists. * * @param file The file. * @return {@code true}: yes<br>{@code false}: no */ public static boolean isFileExists(final File file) { return file != null && file.exists(); } /** * Rename the file. * * @param filePath The path of file. * @param newName The new name of file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean rename(final String filePath, final String newName) { return rename(getFileByPath(filePath), newName); } /** * Rename the file. * * @param file The file. * @param newName The new name of file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean rename(final File file, final String newName) { // file is null then return false if (file == null) return false; // file doesn't exist then return false if (!file.exists()) return false; // the new name is space then return false if (isSpace(newName)) return false; // the new name equals old name then return true if (newName.equals(file.getName())) return true; File newFile = new File(file.getParent() + File.separator + newName); // the new name of file exists then return false return !newFile.exists() && file.renameTo(newFile); } /** * Return whether it is a directory. * * @param dirPath The path of directory. * @return {@code true}: yes<br>{@code false}: no */ public static boolean isDir(final String dirPath) { return isDir(getFileByPath(dirPath)); } /** * Return whether it is a directory. * * @param file The file. * @return {@code true}: yes<br>{@code false}: no */ public static boolean isDir(final File file) { return file != null && file.exists() && file.isDirectory(); } /** * Return whether it is a file. * * @param filePath The path of file. * @return {@code true}: yes<br>{@code false}: no */ public static boolean isFile(final String filePath) { return isFile(getFileByPath(filePath)); } /** * Return whether it is a file. * * @param file The file. * @return {@code true}: yes<br>{@code false}: no */ public static boolean isFile(final File file) { return file != null && file.exists() && file.isFile(); } /** * Create a directory if it doesn't exist, otherwise do nothing. * * @param dirPath The path of directory. * @return {@code true}: exists or creates successfully<br>{@code false}: otherwise */ public static boolean createOrExistsDir(final String dirPath) { return createOrExistsDir(getFileByPath(dirPath)); } /** * Create a directory if it doesn't exist, otherwise do nothing. * * @param file The file. * @return {@code true}: exists or creates successfully<br>{@code false}: otherwise */ public static boolean createOrExistsDir(final File file) { return file != null && (file.exists() ? file.isDirectory() : file.mkdirs()); } /** * Create a file if it doesn't exist, otherwise do nothing. * * @param filePath The path of file. * @return {@code true}: exists or creates successfully<br>{@code false}: otherwise */ public static boolean createOrExistsFile(final String filePath) { return createOrExistsFile(getFileByPath(filePath)); } /** * Create a file if it doesn't exist, otherwise do nothing. * * @param file The file. * @return {@code true}: exists or creates successfully<br>{@code false}: otherwise */ public static boolean createOrExistsFile(final File file) { if (file == null) return false; if (file.exists()) return file.isFile(); if (!createOrExistsDir(file.getParentFile())) return false; try { return file.createNewFile(); } catch (IOException e) { e.printStackTrace(); return false; } } /** * Create a file if it doesn't exist, otherwise delete old file before creating. * * @param filePath The path of file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean createFileByDeleteOldFile(final String filePath) { return createFileByDeleteOldFile(getFileByPath(filePath)); } /** * Create a file if it doesn't exist, otherwise delete old file before creating. * * @param file The file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean createFileByDeleteOldFile(final File file) { if (file == null) return false; // file exists and unsuccessfully delete then return false if (file.exists() && !file.delete()) return false; if (!createOrExistsDir(file.getParentFile())) return false; try { return file.createNewFile(); } catch (IOException e) { e.printStackTrace(); return false; } } /** * Copy the directory. * * @param srcDirPath The path of source directory. * @param destDirPath The path of destination directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyDir(final String srcDirPath, final String destDirPath) { return copyDir(getFileByPath(srcDirPath), getFileByPath(destDirPath)); } /** * Copy the directory. * * @param srcDirPath The path of source directory. * @param destDirPath The path of destination directory. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyDir(final String srcDirPath, final String destDirPath, final OnReplaceListener listener) { return copyDir(getFileByPath(srcDirPath), getFileByPath(destDirPath), listener); } /** * Copy the directory. * * @param srcDir The source directory. * @param destDir The destination directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyDir(final File srcDir, final File destDir) { return copyOrMoveDir(srcDir, destDir, false); } /** * Copy the directory. * * @param srcDir The source directory. * @param destDir The destination directory. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyDir(final File srcDir, final File destDir, final OnReplaceListener listener) { return copyOrMoveDir(srcDir, destDir, listener, false); } /** * Copy the file. * * @param srcFilePath The path of source file. * @param destFilePath The path of destination file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyFile(final String srcFilePath, final String destFilePath) { return copyFile(getFileByPath(srcFilePath), getFileByPath(destFilePath)); } /** * Copy the file. * * @param srcFilePath The path of source file. * @param destFilePath The path of destination file. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyFile(final String srcFilePath, final String destFilePath, final OnReplaceListener listener) { return copyFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), listener); } /** * Copy the file. * * @param srcFile The source file. * @param destFile The destination file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyFile(final File srcFile, final File destFile) { return copyOrMoveFile(srcFile, destFile, false); } /** * Copy the file. * * @param srcFile The source file. * @param destFile The destination file. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean copyFile(final File srcFile, final File destFile, final OnReplaceListener listener) { return copyOrMoveFile(srcFile, destFile, listener, false); } /** * Move the directory. * * @param srcDirPath The path of source directory. * @param destDirPath The path of destination directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveDir(final String srcDirPath, final String destDirPath) { return moveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath)); } /** * Move the directory. * * @param srcDirPath The path of source directory. * @param destDirPath The path of destination directory. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveDir(final String srcDirPath, final String destDirPath, final OnReplaceListener listener) { return moveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath), listener); } /** * Move the directory. * * @param srcDir The source directory. * @param destDir The destination directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveDir(final File srcDir, final File destDir) { return copyOrMoveDir(srcDir, destDir, true); } /** * Move the directory. * * @param srcDir The source directory. * @param destDir The destination directory. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveDir(final File srcDir, final File destDir, final OnReplaceListener listener) { return copyOrMoveDir(srcDir, destDir, listener, true); } /** * Move the file. * * @param srcFilePath The path of source file. * @param destFilePath The path of destination file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveFile(final String srcFilePath, final String destFilePath) { return moveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath)); } /** * Move the file. * * @param srcFilePath The path of source file. * @param destFilePath The path of destination file. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveFile(final String srcFilePath, final String destFilePath, final OnReplaceListener listener) { return moveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), listener); } /** * Move the file. * * @param srcFile The source file. * @param destFile The destination file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveFile(final File srcFile, final File destFile) { return copyOrMoveFile(srcFile, destFile, true); } /** * Move the file. * * @param srcFile The source file. * @param destFile The destination file. * @param listener The replace listener. * @return {@code true}: success<br>{@code false}: fail */ public static boolean moveFile(final File srcFile, final File destFile, final OnReplaceListener listener) { return copyOrMoveFile(srcFile, destFile, listener, true); } private static boolean copyOrMoveDir(final File srcDir, final File destDir, final boolean isMove) { return copyOrMoveDir(srcDir, destDir, new OnReplaceListener() { @Override public boolean onReplace() { return true; } }, isMove); } private static boolean copyOrMoveDir(final File srcDir, final File destDir, final OnReplaceListener listener, final boolean isMove) { if (srcDir == null || destDir == null) return false; // destDir's path locate in srcDir's path then return false String srcPath = srcDir.getPath() + File.separator; String destPath = destDir.getPath() + File.separator; if (destPath.contains(srcPath)) return false; if (!srcDir.exists() || !srcDir.isDirectory()) return false; if (destDir.exists()) { if (listener == null || listener.onReplace()) {// require delete the old directory if (!deleteAllInDir(destDir)) {// unsuccessfully delete then return false return false; } } else { return true; } } if (!createOrExistsDir(destDir)) return false; File[] files = srcDir.listFiles(); for (File file : files) { File oneDestFile = new File(destPath + file.getName()); if (file.isFile()) { if (!copyOrMoveFile(file, oneDestFile, listener, isMove)) return false; } else if (file.isDirectory()) { if (!copyOrMoveDir(file, oneDestFile, listener, isMove)) return false; } } return !isMove || deleteDir(srcDir); } private static boolean copyOrMoveFile(final File srcFile, final File destFile, final boolean isMove) { return copyOrMoveFile(srcFile, destFile, new OnReplaceListener() { @Override public boolean onReplace() { return true; } }, isMove); } private static boolean copyOrMoveFile(final File srcFile, final File destFile, final OnReplaceListener listener, final boolean isMove) { if (srcFile == null || destFile == null) return false; // srcFile equals destFile then return false if (srcFile.equals(destFile)) return false; // srcFile doesn't exist or isn't a file then return false if (!srcFile.exists() || !srcFile.isFile()) return false; if (destFile.exists()) { if (listener == null || listener.onReplace()) {// require delete the old file if (!destFile.delete()) {// unsuccessfully delete then return false return false; } } else { return true; } } if (!createOrExistsDir(destFile.getParentFile())) return false; try { return writeFileFromIS(destFile, new FileInputStream(srcFile), false) && !(isMove && !deleteFile(srcFile)); } catch (FileNotFoundException e) { e.printStackTrace(); return false; } } /** * Delete the directory. * * @param dirPath The path of directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteDir(final String dirPath) { return deleteDir(getFileByPath(dirPath)); } /** * Delete the directory. * * @param dir The directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteDir(final File dir) { if (dir == null) return false; // dir doesn't exist then return true if (!dir.exists()) return true; // dir isn't a directory then return false if (!dir.isDirectory()) return false; File[] files = dir.listFiles(); if (files != null && files.length != 0) { for (File file : files) { if (file.isFile()) { if (!file.delete()) return false; } else if (file.isDirectory()) { if (!deleteDir(file)) return false; } } } return dir.delete(); } /** * Delete the file. * * @param srcFilePath The path of source file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteFile(final String srcFilePath) { return deleteFile(getFileByPath(srcFilePath)); } /** * Delete the file. * * @param file The file. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteFile(final File file) { return file != null && (!file.exists() || file.isFile() && file.delete()); } /** * Delete the all in directory. * * @param dirPath The path of directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteAllInDir(final String dirPath) { return deleteAllInDir(getFileByPath(dirPath)); } /** * Delete the all in directory. * * @param dir The directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteAllInDir(final File dir) { return deleteFilesInDirWithFilter(dir, new FileFilter() { @Override public boolean accept(File pathname) { return true; } }); } /** * Delete all files in directory. * * @param dirPath The path of directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteFilesInDir(final String dirPath) { return deleteFilesInDir(getFileByPath(dirPath)); } /** * Delete all files in directory. * * @param dir The directory. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteFilesInDir(final File dir) { return deleteFilesInDirWithFilter(dir, new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile(); } }); } /** * Delete all files that satisfy the filter in directory. * * @param dirPath The path of directory. * @param filter The filter. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteFilesInDirWithFilter(final String dirPath, final FileFilter filter) { return deleteFilesInDirWithFilter(getFileByPath(dirPath), filter); } /** * Delete all files that satisfy the filter in directory. * * @param dir The directory. * @param filter The filter. * @return {@code true}: success<br>{@code false}: fail */ public static boolean deleteFilesInDirWithFilter(final File dir, final FileFilter filter) { if (dir == null) return false; // dir doesn't exist then return true if (!dir.exists()) return true; // dir isn't a directory then return false if (!dir.isDirectory()) return false; File[] files = dir.listFiles(); if (files != null && files.length != 0) { for (File file : files) { if (filter.accept(file)) { if (file.isFile()) { if (!file.delete()) return false; } else if (file.isDirectory()) { if (!deleteDir(file)) return false; } } } } return true; } /** * Return the files in directory. * <p>Doesn't traverse subdirectories</p> * * @param dirPath The path of directory. * @return the files in directory */ public static List<File> listFilesInDir(final String dirPath) { return listFilesInDir(dirPath, false); } /** * Return the files in directory. * <p>Doesn't traverse subdirectories</p> * * @param dir The directory. * @return the files in directory */ public static List<File> listFilesInDir(final File dir) { return listFilesInDir(dir, false); } /** * Return the files in directory. * * @param dirPath The path of directory. * @param isRecursive True to traverse subdirectories, false otherwise. * @return the files in directory */ public static List<File> listFilesInDir(final String dirPath, final boolean isRecursive) { return listFilesInDir(getFileByPath(dirPath), isRecursive); } /** * Return the files in directory. * * @param dir The directory. * @param isRecursive True to traverse subdirectories, false otherwise. * @return the files in directory */ public static List<File> listFilesInDir(final File dir, final boolean isRecursive) { return listFilesInDirWithFilter(dir, new FileFilter() { @Override public boolean accept(File pathname) { return true; } }, isRecursive); } /** * Return the files that satisfy the filter in directory. * <p>Doesn't traverse subdirectories</p> * * @param dirPath The path of directory. * @param filter The filter. * @return the files that satisfy the filter in directory */ public static List<File> listFilesInDirWithFilter(final String dirPath, final FileFilter filter) { return listFilesInDirWithFilter(getFileByPath(dirPath), filter, false); } /** * Return the files that satisfy the filter in directory. * <p>Doesn't traverse subdirectories</p> * * @param dir The directory. * @param filter The filter. * @return the files that satisfy the filter in directory */ public static List<File> listFilesInDirWithFilter(final File dir, final FileFilter filter) { return listFilesInDirWithFilter(dir, filter, false); } /** * Return the files that satisfy the filter in directory. * * @param dirPath The path of directory. * @param filter The filter. * @param isRecursive True to traverse subdirectories, false otherwise. * @return the files that satisfy the filter in directory */ public static List<File> listFilesInDirWithFilter(final String dirPath, final FileFilter filter, final boolean isRecursive) { return listFilesInDirWithFilter(getFileByPath(dirPath), filter, isRecursive); } /** * Return the files that satisfy the filter in directory. * * @param dir The directory. * @param filter The filter. * @param isRecursive True to traverse subdirectories, false otherwise. * @return the files that satisfy the filter in directory */ public static List<File> listFilesInDirWithFilter(final File dir, final FileFilter filter, final boolean isRecursive) { if (!isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); if (files != null && files.length != 0) { for (File file : files) { if (filter.accept(file)) { list.add(file); } if (isRecursive && file.isDirectory()) { //noinspection ConstantConditions list.addAll(listFilesInDirWithFilter(file, filter, true)); } } } return list; } /** * Return the time that the file was last modified. * * @param filePath The path of file. * @return the time that the file was last modified */ public static long getFileLastModified(final String filePath) { return getFileLastModified(getFileByPath(filePath)); } /** * Return the time that the file was last modified. * * @param file The file. * @return the time that the file was last modified */ public static long getFileLastModified(final File file) { if (file == null) return -1; return file.lastModified(); } /** * Return the charset of file simply. * * @param filePath The path of file. * @return the charset of file simply */ public static String getFileCharsetSimple(final String filePath) { return getFileCharsetSimple(getFileByPath(filePath)); } /** * Return the charset of file simply. * * @param file The file. * @return the charset of file simply */ public static String getFileCharsetSimple(final File file) { int p = 0; InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(file)); p = (is.read() << 8) + is.read(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } switch (p) { case 0xefbb: return "UTF-8"; case 0xfffe: return "Unicode"; case 0xfeff: return "UTF-16BE"; default: return "GBK"; } } /** * Return the number of lines of file. * * @param filePath The path of file. * @return the number of lines of file */ public static int getFileLines(final String filePath) { return getFileLines(getFileByPath(filePath)); } /** * Return the number of lines of file. * * @param file The file. * @return the number of lines of file */ public static int getFileLines(final File file) { int count = 1; InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[1024]; int readChars; if (LINE_SEP.endsWith("\n")) { while ((readChars = is.read(buffer, 0, 1024)) != -1) { for (int i = 0; i < readChars; ++i) { if (buffer[i] == '\n') ++count; } } } else { while ((readChars = is.read(buffer, 0, 1024)) != -1) { for (int i = 0; i < readChars; ++i) { if (buffer[i] == '\r') ++count; } } } } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } return count; } /** * Return the size of directory. * * @param dirPath The path of directory. * @return the size of directory */ public static String getDirSize(final String dirPath) { return getDirSize(getFileByPath(dirPath)); } /** * Return the size of directory. * * @param dir The directory. * @return the size of directory */ public static String getDirSize(final File dir) { long len = getDirLength(dir); return len == -1 ? "" : byte2FitMemorySize(len); } /** * Return the length of file. * * @param filePath The path of file. * @return the length of file */ public static String getFileSize(final String filePath) { long len = getFileLength(filePath); return len == -1 ? "" : byte2FitMemorySize(len); } /** * Return the length of file. * * @param file The file. * @return the length of file */ public static String getFileSize(final File file) { long len = getFileLength(file); return len == -1 ? "" : byte2FitMemorySize(len); } /** * Return the length of directory. * * @param dirPath The path of directory. * @return the length of directory */ public static long getDirLength(final String dirPath) { return getDirLength(getFileByPath(dirPath)); } /** * Return the length of directory. * * @param dir The directory. * @return the length of directory */ public static long getDirLength(final File dir) { if (!isDir(dir)) return -1; long len = 0; File[] files = dir.listFiles(); if (files != null && files.length != 0) { for (File file : files) { if (file.isDirectory()) { len += getDirLength(file); } else { len += file.length(); } } } return len; } /** * Return the length of file. * * @param filePath The path of file. * @return the length of file */ public static long getFileLength(final String filePath) { boolean isURL = filePath.matches("[a-zA-z]+://[^\\s]*"); if (isURL) { try { HttpURLConnection conn = (HttpURLConnection) new URL(filePath).openConnection(); conn.setRequestProperty("Accept-Encoding", "identity"); conn.connect(); if (conn.getResponseCode() == 200) { return conn.getContentLength(); } return -1; } catch (IOException e) { e.printStackTrace(); } } return getFileLength(getFileByPath(filePath)); } /** * Return the length of file. * * @param file The file. * @return the length of file */ public static long getFileLength(final File file) { if (!isFile(file)) return -1; return file.length(); } /** * Return the MD5 of file. * * @param filePath The path of file. * @return the md5 of file */ public static String getFileMD5ToString(final String filePath) { File file = isSpace(filePath) ? null : new File(filePath); return getFileMD5ToString(file); } /** * Return the MD5 of file. * * @param file The file. * @return the md5 of file */ public static String getFileMD5ToString(final File file) { return bytes2HexString(getFileMD5(file)); } /** * Return the MD5 of file. * * @param filePath The path of file. * @return the md5 of file */ public static byte[] getFileMD5(final String filePath) { return getFileMD5(getFileByPath(filePath)); } /** * Return the MD5 of file. * * @param file The file. * @return the md5 of file */ public static byte[] getFileMD5(final File file) { if (file == null) return null; DigestInputStream dis = null; try { FileInputStream fis = new FileInputStream(file); MessageDigest md = MessageDigest.getInstance("MD5"); dis = new DigestInputStream(fis, md); byte[] buffer = new byte[1024 * 256]; while (true) { if (!(dis.read(buffer) > 0)) break; } md = dis.getMessageDigest(); return md.digest(); } catch (NoSuchAlgorithmException | IOException e) { e.printStackTrace(); } finally { try { if (dis != null) { dis.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } /** * Return the file's path of directory. * * @param file The file. * @return the file's path of directory */ public static String getDirName(final File file) { if (file == null) return ""; return getDirName(file.getAbsolutePath()); } /** * Return the file's path of directory. * * @param filePath The path of file. * @return the file's path of directory */ public static String getDirName(final String filePath) { if (isSpace(filePath)) return ""; int lastSep = filePath.lastIndexOf(File.separator); return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1); } /** * Return the name of file. * * @param file The file. * @return the name of file */ public static String getFileName(final File file) { if (file == null) return ""; return getFileName(file.getAbsolutePath()); } /** * Return the name of file. * * @param filePath The path of file. * @return the name of file */ public static String getFileName(final String filePath) { if (isSpace(filePath)) return ""; int lastSep = filePath.lastIndexOf(File.separator); return lastSep == -1 ? filePath : filePath.substring(lastSep + 1); } /** * Return the name of file without extension. * * @param file The file. * @return the name of file without extension */ public static String getFileNameNoExtension(final File file) { if (file == null) return ""; return getFileNameNoExtension(file.getPath()); } /** * Return the name of file without extension. * * @param filePath The path of file. * @return the name of file without extension */ public static String getFileNameNoExtension(final String filePath) { if (isSpace(filePath)) return ""; int lastPoi = filePath.lastIndexOf('.'); int lastSep = filePath.lastIndexOf(File.separator); if (lastSep == -1) { return (lastPoi == -1 ? filePath : filePath.substring(0, lastPoi)); } if (lastPoi == -1 || lastSep > lastPoi) { return filePath.substring(lastSep + 1); } return filePath.substring(lastSep + 1, lastPoi); } /////////////////////////////////////////////////////////////////////////// // copy from ConvertUtils /////////////////////////////////////////////////////////////////////////// /** * Return the extension of file. * * @param file The file. * @return the extension of file */ public static String getFileExtension(final File file) { if (file == null) return ""; return getFileExtension(file.getPath()); } /** * Return the extension of file. * * @param filePath The path of file. * @return the extension of file */ public static String getFileExtension(final String filePath) { if (isSpace(filePath)) return ""; int lastPoi = filePath.lastIndexOf('.'); int lastSep = filePath.lastIndexOf(File.separator); if (lastPoi == -1 || lastSep >= lastPoi) return ""; return filePath.substring(lastPoi + 1); } private static String bytes2HexString(final byte[] bytes) { if (bytes == null) return ""; int len = bytes.length; if (len <= 0) return ""; char[] ret = new char[len << 1]; for (int i = 0, j = 0; i < len; i++) { ret[j++] = HEX_DIGITS[bytes[i] >> 4 & 0x0f]; ret[j++] = HEX_DIGITS[bytes[i] & 0x0f]; } return new String(ret); } @SuppressLint("DefaultLocale") private static String byte2FitMemorySize(final long byteNum) { if (byteNum < 0) { return "shouldn't be less than zero!"; } else if (byteNum < 1024) { return String.format("%.3fB", (double) byteNum); } else if (byteNum < 1048576) { return String.format("%.3fKB", (double) byteNum / 1024); } else if (byteNum < 1073741824) { return String.format("%.3fMB", (double) byteNum / 1048576); } else { return String.format("%.3fGB", (double) byteNum / 1073741824); } } private static boolean isSpace(final String s) { if (s == null) return true; for (int i = 0, len = s.length(); i < len; ++i) { if (!Character.isWhitespace(s.charAt(i))) { return false; } } return true; } /** * 调用系统软件打开文件, 会自动判断文件类型 * * @author 工藤一号 [email protected] * @date 2017年6月8日 上午10:46:50 */ public static void openFileBySystemApp(Context context, File file) { Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 设置intent的Action属性 intent.setAction(Intent.ACTION_VIEW); // 获取文件file的MIME类型 String type = getMIMEType(file); // 设置intent的data和Type属性。 intent.setDataAndType(/* uri */Uri.fromFile(file), type); // 跳转 context.startActivity(intent); } /** * 得到文件类型 * * @author 工藤一号 [email protected] * @date 2017年6月8日 上午10:48:30 */ public static String getMIMEType(File file) { String type = "*/*"; String fName = file.getName(); // 获取后缀名前的分隔符"."在fName中的位置。 int dotIndex = fName.lastIndexOf("."); if (dotIndex < 0) { return type; } /* 获取文件的后缀名 */ String end = fName.substring(dotIndex, fName.length()).toLowerCase(); if (end == "") return type; // 在MIME和文件类型的匹配表中找到对应的MIME类型。 for (int i = 0; i < MIME_MapTable.length; i++) { if (end.equals(MIME_MapTable[i][0])) type = MIME_MapTable[i][1]; } return type; } /** * 根据文件路径拷贝文件 * * @param resourceFile 源文件 * @param targetPath 目标路径(包含文件名和文件格式) * @return boolean 成功true、失败false */ public static boolean copyFile(File resourceFile, String targetPath, String fileName) { boolean result = false; if (resourceFile == null || TextUtils.isEmpty(targetPath)) { return result; } File target = new File(targetPath); if (target.exists()) { target.delete(); // 已存在的话先删除 } else { try { target.mkdirs(); } catch (Exception e) { e.printStackTrace(); } } File targetFile = new File(targetPath.concat(fileName)); if (targetFile.exists()) { targetFile.delete(); } else { try { targetFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } FileChannel resourceChannel = null; FileChannel targetChannel = null; try { resourceChannel = new FileInputStream(resourceFile).getChannel(); targetChannel = new FileOutputStream(targetFile).getChannel(); resourceChannel.transferTo(0, resourceChannel.size(), targetChannel); result = true; } catch (FileNotFoundException e) { e.printStackTrace(); return result; } catch (IOException e) { e.printStackTrace(); return result; } try { resourceChannel.close(); targetChannel.close(); } catch (IOException e) { e.printStackTrace(); } return result; } public interface OnReplaceListener { boolean onReplace(); } }