package cn.sddman.arcgistool.util; import android.content.Context; import android.os.Environment; import android.text.TextUtils; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileTools { private static final String TAG = "FileTools"; public static final int FLAG_SHORTER = 1 << 0; public static final long KB_IN_BYTES = 1024; public static final long MB_IN_BYTES = KB_IN_BYTES * 1024; public static final long GB_IN_BYTES = MB_IN_BYTES * 1024; public static final long TB_IN_BYTES = GB_IN_BYTES * 1024; public static final long PB_IN_BYTES = TB_IN_BYTES * 1024; public static final String byteShort = "B" ; public static final String kilobyteShort= "KB" ; public static final String megabyteShort= "MB" ; public static final String gigabyteShort= "GB" ; public static final String terabyteShort= "TB" ; public static final String petabyteShort= "PB" ; /** * 获取SD卡路径 * * @return */ public static String getSDCardPath() { return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator; } /** * 获取系统存储路径 * * @return */ public static String getRootDirectoryPath() { return Environment.getRootDirectory().getAbsolutePath(); } /** * 格式化文件大小为可读字符串 * @param fileSize long形式的文件大小 * @param formatSort true表示只保留一位小数点 * @return */ public static String getReadableFileSize(long fileSize, boolean formatSort) { if(formatSort){ return formatShortFileSize(fileSize); }else{ return formatFileSize(fileSize); } } /** * 获取文件大小 * @param file * @return * @throws Exception */ public static long getFileSize(File file){ if(!file.exists()){ return 0; } FileInputStream fis = null; try{ fis = new FileInputStream(file); return fis.available(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(fis != null){ closeQuietly(fis); } } return 0; } /** * 获取文件最新修改时间 * @param filePath * @return */ public static long getFileModifyTime(String filePath) { if (null == filePath) { return 0; } File file = new File(filePath); if (file == null || !file.exists()) { return 0; } return file.lastModified(); } /** * 判断输入文件是否存在 * @param path * @return */ public static boolean exists(String path){ if(TextUtils.isEmpty(path) || TextUtils.isEmpty(path)){ return false; } return new File(path).exists(); } /** * 复制文件,只能复制非目录文件,需要复制目录请使用{@link #copyDir(String, String)} * @param srcFile 需要复制的文件 * @param dstFile 复制之后的文件 * @return 复制成功返回true,否则返回false * @throws IOException */ public static boolean copyFile(String srcFile,String dstFile) throws IOException{ if(TextUtils.isEmpty(srcFile) || TextUtils.isEmpty(dstFile)){ return false; } File destFile = new File(dstFile); File sFile = new File(srcFile); if(!sFile.exists()){ return false; } if (destFile.exists()) { destFile.delete(); } FileInputStream inputStream = null; FileOutputStream out = null; try { inputStream = new FileInputStream(sFile); out = new FileOutputStream(destFile); }catch (FileNotFoundException e){ return false; } try { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) >= 0) { out.write(buffer, 0, bytesRead); } } finally { out.flush(); try { out.getFD().sync(); } catch (IOException e) { } out.close(); } return true; } /** * 复制目录 * @param srcDir 源目录 * @param dstDir 目标目录 * @return * @throws IOException */ public static boolean copyDir(String srcDir,String dstDir)throws IOException { if(TextUtils.isEmpty(srcDir) || TextUtils.isEmpty(dstDir)){ return false; } File srcDirFile = new File(srcDir); if(!srcDirFile.exists()){ return false; } if(!srcDirFile.isDirectory()){ return false; } File dstDirFile = new File(dstDir); if(!dstDirFile.exists()){ dstDirFile.mkdirs(); } File[] listFiles = srcDirFile.listFiles(); if(listFiles == null || listFiles.length == 0){ return false; } for(File child : listFiles){ if(child.isFile()){ copyFile(child.getAbsolutePath(),dstDirFile.getAbsolutePath()+ File.separator+child.getName()); }else{ copyDir(child.getAbsolutePath(),dstDirFile.getAbsolutePath()+ File.separator+child.getName()); } } return true; } /** * 文件剪切 * @param srcFile * @param dstFile dstFile必须是最后剪切之后的完整文件路径名 * @return */ public static boolean moveFile(String srcFile,String dstFile){ if(TextUtils.isEmpty(srcFile) || TextUtils.isEmpty(dstFile)){ return false; } File src = new File(srcFile); File dst = new File(dstFile); if(!src.exists()){ return false; } int srcStorageIndex = src.getAbsolutePath().indexOf("/",1); int dstStorageIndex = dst.getAbsolutePath().indexOf("/",1); String srcStorage = srcFile.substring(0,srcStorageIndex); String dstStorage = dstFile.substring(0,dstStorageIndex); //如果是同磁盘剪切文件,直接使用rename即可,提高剪切速度,不同磁盘间使用 //先拷贝后删除的操作 if(!srcStorage.equals(dstStorage)){ return src.renameTo(new File(dstFile)); }else{ try { boolean isDir = src.isDirectory(); boolean success = isDir?copyDir(srcFile,dstFile):copyFile(srcFile,dstFile); if(success){ if(isDir){ deleteDir(srcFile); }else{ deleteFile(srcFile); } } return success; } catch (IOException e) { e.printStackTrace(); } } return false; } /** * 重命名文件 * @param oldFile * @param newName * @return */ public static boolean renameFile(File oldFile ,String newName){ if(TextUtils.isEmpty(newName)){ return false; } if(oldFile.exists()){ return oldFile.renameTo(new File(oldFile.getParent(),newName)); } return false; } /** * 删除目标文件,该文件不能是目录,如果是目录请使用{@link #deleteDir(String)} * @param srcFile * @return */ public static boolean deleteFile(String srcFile){ if(TextUtils.isEmpty(srcFile) || TextUtils.isEmpty(srcFile)){ return false; } File file = new File(srcFile); if(file.exists() && !file.isDirectory()){ return file.delete(); } return false; } /** * 删除指定路径的目录,包括该目录的子目录以及子文件 * @param dirFile * @return */ public static boolean deleteDir(String dirFile){ if(TextUtils.isEmpty(dirFile) || TextUtils.isEmpty(dirFile)){ return false; } File oldFile = new File(dirFile); File file = new File(oldFile.getAbsolutePath() + System.currentTimeMillis()); oldFile.renameTo(file); if (file == null || !file.exists()) { return false; } if (file.isDirectory()) { File[] list = file.listFiles(); for (int i = 0; i < list.length; i++) { if (list[i].isDirectory()) { deleteDir(list[i].getAbsolutePath()); } else { list[i].delete(); } } } file.delete(); return true; } /** * 根据指定文件名创建文件 * @param file * @return */ public static boolean makeNewFile(String file){ if(TextUtils.isEmpty(file)){ return false; } File newFile = new File(file); boolean success = false; if(newFile.exists()){ return true; }else { try { success = newFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); success = false; } } return success; } /** * 在指定目录中创建一些子目录 * @param parentPath 自定父目录 * @param dirNames 需要创建的子目录数组 * @return */ public static boolean mkdirsInParent(String parentPath,String... dirNames){ if(!exists(parentPath)){ if(!(new File(parentPath).mkdirs())){ return false; } } File childDirFile = null; boolean success = false; for(String child : dirNames){ childDirFile = new File(parentPath,child); success = childDirFile.mkdirs(); if(!success){ } } return success; } /** * 批量创建文件目录,需要指定目录完整路径: * 例如: * <code>sdcard/Android/TestDirName</code> * @param dirNames 需要创建的目录路径集合 * @return */ public static boolean mkdirs(String... dirNames){ File childDirFile = null; boolean success = false; for(String dirPath : dirNames){ childDirFile = new File(dirPath); success = childDirFile.mkdirs(); if(!success){ } } return success; } /** * 判断sdcard是否已经挂载 * @param context * @return */ public static boolean hasSdcard(Context context){ return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED; } /** * 检查目标文件是否有读取权限 * @param targetFile * @return */ public static boolean checkFileReadPermission(String targetFile){ if(TextUtils.isEmpty(targetFile)){ return false; } File file = new File(targetFile); if(!file.exists()){ return false; } return file.canRead(); } /** * 检查目标文件是否有写权限 * @param targetFile * @return */ public static boolean checkFileWritePermission(String targetFile){ if(TextUtils.isEmpty(targetFile)){ return false; } File file = new File(targetFile); if(!file.exists()){ return false; } return file.canWrite(); } /** * 关闭可关闭的数据 * @param closeable */ public static void closeQuietly(Closeable closeable){ if (closeable != null) { try { closeable.close(); } catch (RuntimeException e) { throw e; } catch (Exception e) { // Ignore. } } } static String formatFileSize( long sizeBytes) { return formatBytes(sizeBytes, 0); } static String formatShortFileSize( long sizeBytes) { return formatBytes(sizeBytes, FLAG_SHORTER); } static String formatBytes(long sizeBytes, int flags) { final boolean isNegative = (sizeBytes < 0); float result = isNegative ? -sizeBytes : sizeBytes; String suffix = byteShort; long mult = 1; if (result > 900) { suffix = kilobyteShort; mult = KB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = megabyteShort; mult = MB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = gigabyteShort; mult = GB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = terabyteShort; mult = TB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = petabyteShort; mult = PB_IN_BYTES; result = result / 1024; } // Note we calculate the rounded long by ourselves, but still let String.format() // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to // floating point errors. final int roundFactor; final String roundFormat; if (mult == 1 || result >= 100) { roundFactor = 1; roundFormat = "%.0f"; } else if (result < 1) { roundFactor = 100; roundFormat = "%.2f"; } else if (result < 10) { if ((flags & FLAG_SHORTER) != 0) { roundFactor = 10; roundFormat = "%.1f"; } else { roundFactor = 100; roundFormat = "%.2f"; } } else { // 10 <= result < 100 if ((flags & FLAG_SHORTER) != 0) { roundFactor = 1; roundFormat = "%.0f"; } else { roundFactor = 100; roundFormat = "%.2f"; } } if (isNegative) { result = -result; } final String roundedString = String.format(roundFormat, result); return roundedString+suffix; } }