/* * Copyright 2015 Yan Zhenjie * * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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.yidianling.common.tools; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.StatFs; import android.provider.DocumentsContract; import android.provider.MediaStore; import androidx.core.content.FileProvider; import android.util.Base64; import android.util.Log; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; import static com.yidianling.common.tools.RxConstTool.KB; //import android.util.Log; /** * Created in Sep 10, 2016 4:22:18 PM. * * @author Vondear. */ public class RxFileTool { public static final int BUFSIZE = 1024 * 8; private static final String TAG = "RxFileTool"; private static final String FOLDER_NAME ="/yidianling"; ; /** * 得到SD卡根目录. */ public static File getRootPath() { File path = null; if (sdCardIsAvailable()) { path = Environment.getExternalStorageDirectory(); // 取得sdcard文件路径 } else { path = Environment.getDataDirectory(); } return path; } /** * 获取的目录默认没有最后的”/”,需要自己加上 * 获取本应用图片缓存目录 * * @return */ public static File getCecheFolder(Context context) { File folder = new File(context.getCacheDir(), "IMAGECACHE"); if (!folder.exists()) { folder.mkdir(); } return folder; } /** * 判断SD卡是否可用 * * @return true : 可用<br>false : 不可用 */ public static boolean isSDCardEnable() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } /** * 获取SD卡路径 * <p>一般是/storage/emulated/0/</p> * * @return SD卡路径 */ public static String getSDCardPath() { if (!isSDCardEnable()) return "sdcard unable!"; return Environment.getExternalStorageDirectory().getPath() + File.separator; } public static String getStorageDirectory(Context context) { return isSDCardEnable() ? Environment.getExternalStorageDirectory().getPath() + FOLDER_NAME : context.getCacheDir().getPath() + FOLDER_NAME; } /** * 获取SD卡Data路径 * * @return SD卡Data路径 */ public static String getDataPath() { if (!isSDCardEnable()) return "sdcard unable!"; return Environment.getDataDirectory().getPath(); } /** * 获取SD卡剩余空间 * * @return SD卡剩余空间 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public static String getFreeSpace() { if (!isSDCardEnable()) return "sdcard unable!"; StatFs stat = new StatFs(getSDCardPath()); long blockSize, availableBlocks; availableBlocks = stat.getAvailableBlocksLong(); blockSize = stat.getBlockSizeLong(); return RxDataTool.byte2FitSize(availableBlocks * blockSize); } /** * SD卡是否可用. */ public static boolean sdCardIsAvailable() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File sd = new File(Environment.getExternalStorageDirectory().getPath()); return sd.canWrite(); } else return false; } /** * 文件或者文件夹是否存在. */ public static boolean fileExists(String filePath) { File file = new File(filePath); return file.exists(); } /** * 删除指定文件夹下所有文件, 不保留文件夹. */ public static boolean delAllFile(String path) { boolean flag = false; File file = new File(path); if (!file.exists()) { return flag; } if (file.isFile()) { file.delete(); return true; } File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { File exeFile = files[i]; if (exeFile.isDirectory()) { delAllFile(exeFile.getAbsolutePath()); } else { exeFile.delete(); } } file.delete(); return flag; } /** * 删除目录下的所有文件 * * @param dirPath 目录路径 * @return {@code true}: 删除成功<br>{@code false}: 删除失败 */ public static boolean deleteFilesInDir(String dirPath) { return deleteFilesInDir(getFileByPath(dirPath)); } /** * 删除目录下的所有文件 * * @param dir 目录 * @return {@code true}: 删除成功<br>{@code false}: 删除失败 */ public static boolean deleteFilesInDir(File dir) { if (dir == null) return false; // 目录不存在返回true if (!dir.exists()) return true; // 不是目录返回false if (!dir.isDirectory()) return false; // 现在文件存在且是文件夹 File[] files = dir.listFiles(); if (files != null && files.length != 0) { for (File file : files) { if (file.isFile()) { if (!deleteFile(file)) return false; } else if (file.isDirectory()) { if (!deleteDir(file)) return false; } } } return true; } /** * 清除内部缓存 * <p>/data/data/com.xxx.xxx/cache</p> * * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanInternalCache(Context context) { return RxFileTool.deleteFilesInDir(context.getCacheDir()); } /** * 清除内部文件 * <p>/data/data/com.xxx.xxx/files</p> * * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanInternalFiles(Context context) { return RxFileTool.deleteFilesInDir(context.getFilesDir()); } /** * 清除内部数据库 * <p>/data/data/com.xxx.xxx/databases</p> * * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanInternalDbs(Context context) { return RxFileTool.deleteFilesInDir(context.getFilesDir().getParent() + File.separator + "databases"); } /** * 根据名称清除数据库 * <p>/data/data/com.xxx.xxx/databases/dbName</p> * * @param dbName 数据库名称 * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanInternalDbByName(Context context, String dbName) { return context.deleteDatabase(dbName); } /** * 清除内部SP * <p>/data/data/com.xxx.xxx/shared_prefs</p> * * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanInternalSP(Context context) { return RxFileTool.deleteFilesInDir(context.getFilesDir().getParent() + File.separator + "shared_prefs"); } /** * 清除外部缓存 * <p>/storage/emulated/0/android/data/com.xxx.xxx/cache</p> * * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanExternalCache(Context context) { return RxFileTool.isSDCardEnable() && RxFileTool.deleteFilesInDir(context.getExternalCacheDir()); } /** * 清除自定义目录下的文件 * * @param dirPath 目录路径 * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanCustomCache(String dirPath) { return RxFileTool.deleteFilesInDir(dirPath); } /** * 清除自定义目录下的文件 * * @param dir 目录 * @return {@code true}: 清除成功<br>{@code false}: 清除失败 */ public static boolean cleanCustomCache(File dir) { return RxFileTool.deleteFilesInDir(dir); } /** * 文件复制. */ public static boolean copy(String srcFile, String destFile) { try { FileInputStream in = new FileInputStream(srcFile); FileOutputStream out = new FileOutputStream(destFile); byte[] bytes = new byte[1024]; int c; while ((c = in.read(bytes)) != -1) { out.write(bytes, 0, c); } in.close(); out.flush(); out.close(); } catch (Exception e) { return false; } return true; } /** * 复制整个文件夹内. * * @param oldPath string 原文件路径如:c:/fqf. * @param newPath string 复制后路径如:f:/fqf/ff. */ public static void copyFolder(String oldPath, String newPath) { try { (new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹 File a = new File(oldPath); String[] file = a.list(); File temp = null; for (int i = 0; i < file.length; i++) { if (oldPath.endsWith(File.separator)) { temp = new File(oldPath + file[i]); } else { temp = new File(oldPath + File.separator + file[i]); } if (temp.isFile()) { FileInputStream input = new FileInputStream(temp); FileOutputStream output = new FileOutputStream(newPath + "/" + (temp.getName()).toString()); byte[] b = new byte[1024 * 5]; int len; while ((len = input.read(b)) != -1) { output.write(b, 0, len); } output.flush(); output.close(); input.close(); } if (temp.isDirectory()) {// 如果是子文件夹 copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]); } } } catch (NullPointerException e) { } catch (Exception e) { } } /** * 重命名文件. */ public static boolean renameFile(String resFilePath, String newFilePath) { File resFile = new File(resFilePath); File newFile = new File(newFilePath); return resFile.renameTo(newFile); } /** * 获取磁盘可用空间. */ @SuppressWarnings("deprecation") @SuppressLint("NewApi") public static long getSDCardAvailaleSize() { File path = getRootPath(); StatFs stat = new StatFs(path.getPath()); long blockSize, availableBlocks; if (Build.VERSION.SDK_INT >= 18) { blockSize = stat.getBlockSizeLong(); availableBlocks = stat.getAvailableBlocksLong(); } else { blockSize = stat.getBlockSize(); availableBlocks = stat.getAvailableBlocks(); } return availableBlocks * blockSize; } /** * 获取某个目录可用大小. */ @SuppressLint("NewApi") @SuppressWarnings("deprecation") public static long getDirSize(String path) { StatFs stat = new StatFs(path); long blockSize, availableBlocks; if (Build.VERSION.SDK_INT >= 18) { blockSize = stat.getBlockSizeLong(); availableBlocks = stat.getAvailableBlocksLong(); } else { blockSize = stat.getBlockSize(); availableBlocks = stat.getAvailableBlocks(); } return availableBlocks * blockSize; } /** * 获取文件或者文件夹大小. */ public static long getFileAllSize(String path) { File file = new File(path); if (file.exists()) { if (file.isDirectory()) { File[] childrens = file.listFiles(); long size = 0; for (File f : childrens) { size += getFileAllSize(f.getPath()); } return size; } else { return file.length(); } } else { return 0; } } /** * 创建一个文件. */ public static boolean initFile(String path) { boolean result = false; try { File file = new File(path); if (!file.exists()) { result = file.createNewFile(); } else if (file.isDirectory()) { file.delete(); result = file.createNewFile(); } else if (file.exists()) { result = true; } } catch (IOException e) { e.printStackTrace(); } return result; } /** * 创建一个文件夹. */ public static boolean initDirectory(String path) { boolean result = false; File file = new File(path); if (!file.exists()) { result = file.mkdir(); } else if (!file.isDirectory()) { file.delete(); result = file.mkdir(); } else if (file.exists()) { result = true; } return result; } /** * 复制文件. */ public static void copyFile(File from, File to) throws IOException { if (!from.exists()) { throw new IOException("The source file not exist: " + from.getAbsolutePath()); } FileInputStream fis = new FileInputStream(from); try { copyFile(fis, to); } finally { fis.close(); } } /** * 从InputStream流复制文件. */ public static long copyFile(InputStream from, File to) throws IOException { long totalBytes = 0; FileOutputStream fos = new FileOutputStream(to, false); try { byte[] data = new byte[1024]; int len; while ((len = from.read(data)) > -1) { fos.write(data, 0, len); totalBytes += len; } fos.flush(); } finally { fos.close(); } return totalBytes; } /** * 保存InputStream流到文件. */ public static void saveFile(InputStream inputStream, String filePath) { try { OutputStream outputStream = new FileOutputStream(new File(filePath), false); int len; byte[] buffer = new byte[1024]; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } outputStream.flush(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 用UTF8保存一个文件. */ public static void saveFileUTF8(String path, String content, Boolean append) throws IOException { FileOutputStream fos = new FileOutputStream(path, append); Writer out = new OutputStreamWriter(fos, "UTF-8"); out.write(content); out.flush(); out.close(); fos.flush(); fos.close(); } /** * 用UTF8读取一个文件. */ public static String getFileUTF8(String path) { String result = ""; InputStream fin = null; try { fin = new FileInputStream(path); int length = fin.available(); byte[] buffer = new byte[length]; fin.read(buffer); fin.close(); result = new String(buffer, "UTF-8"); } catch (Exception e) { } return result; } /** * 得到一个文件Intent. */ public static Intent getFileIntent(String path, String mimeType) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(path)), mimeType); return intent; } /** * 获取缓存目录 * * @param context * @return */ public static String getDiskCacheDir(Context context) { String cachePath = null; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return cachePath; } /** * 获取缓存视频文件目录 * * @param context * @return */ public static String getDiskFileDir(Context context) { String cachePath = null; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES).getPath(); } else { cachePath = context.getFilesDir().getPath(); } return cachePath; } /** * 多个文件合并 * * @param outFile * @param files */ public static void mergeFiles(Context context, File outFile, List<File> files) { FileChannel outChannel = null; try { outChannel = new FileOutputStream(outFile).getChannel(); for (File f : files) { FileChannel fc = new FileInputStream(f).getChannel(); ByteBuffer bb = ByteBuffer.allocate(BUFSIZE); while (fc.read(bb) != -1) { bb.flip(); outChannel.write(bb); bb.clear(); } fc.close(); } Log.d(TAG, "拼接完成"); } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if (outChannel != null) { outChannel.close(); } } catch (IOException ignore) { } } } /** * 将在线的m3u8替换成本地的m3u8 * * @param context 实体 * @param file 在线的m3u8 * @param pathList 本地的ts文件 * @return */ public static String getNativeM3u(final Context context, File file, List<File> pathList) { InputStream in = null; int num = 0; //需要生成的目标buff StringBuffer buf = new StringBuffer(); try { if (file != null) { in = new FileInputStream(file); } BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line = ""; while ((line = reader.readLine()) != null) { if (line.length() > 0 && line.startsWith("http://")) { //replce 这行的内容 // Log.d("ts替换", line + " replce " + pathList.get(num).getAbsolutePath()); buf.append("file:" + pathList.get(num).getAbsolutePath() + "\r\n"); num++; } else { buf.append(line + "\r\n"); } } in.close(); write(file.getAbsolutePath(), buf.toString()); Log.d("ts替换", "ts替换完成"); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } return buf.toString(); } /** * 将字符串 保存成 文件 * * @param filePath * @param content */ public static void write(String filePath, String content) { BufferedWriter bw = null; try { //根据文件路径创建缓冲输出流 bw = new BufferedWriter(new FileWriter(filePath)); // 将内容写入文件中 bw.write(content); // Log.d("M3U8替换", "替换完成"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 if (bw != null) { try { bw.close(); } catch (IOException e) { bw = null; } } } } /** * 获取 搜索的路径 下的 所有 后缀 的文件 * * @param fileAbsolutePath 搜索的路径 * @param suffix 文件后缀 * @return */ public static Vector<String> GetAllFileName(String fileAbsolutePath, String suffix) { Vector<String> vecFile = new Vector<String>(); File file = new File(fileAbsolutePath); File[] subFile = file.listFiles(); for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) { // 判断是否为文件夹 if (!subFile[iFileLength].isDirectory()) { String filename = subFile[iFileLength].getName(); // 判断是否为suffix结尾 if (filename.trim().toLowerCase().endsWith(suffix)) { vecFile.add(filename); } } } return vecFile; } //---------------------------------------------------------------------------------------------- /** * 根据文件路径获取文件 * * @param filePath 文件路径 * @return 文件 */ public static File getFileByPath(String filePath) { return RxDataTool.isNullString(filePath) ? null : new File(filePath); } //============================================================================================== /** * 判断文件是否存在 * * @param filePath 文件路径 * @return {@code true}: 存在<br>{@code false}: 不存在 */ public static boolean isFileExists(String filePath) { return isFileExists(getFileByPath(filePath)); } /** * 判断文件是否存在 * * @param file 文件 * @return {@code true}: 存在<br>{@code false}: 不存在 */ public static boolean isFileExists(File file) { return file != null && file.exists(); } /** * 判断是否是目录 * * @param dirPath 目录路径 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isDir(String dirPath) { return isDir(getFileByPath(dirPath)); } /** * 判断是否是目录 * * @param file 文件 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isDir(File file) { return isFileExists(file) && file.isDirectory(); } /** * 判断是否是文件 * * @param filePath 文件路径 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isFile(String filePath) { return isFile(getFileByPath(filePath)); } /** * 判断是否是文件 * * @param file 文件 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isFile(File file) { return isFileExists(file) && file.isFile(); } /** * 判断目录是否存在,不存在则判断是否创建成功 * * @param dirPath 文件路径 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败 */ public static boolean createOrExistsDir(String dirPath) { return createOrExistsDir(getFileByPath(dirPath)); } /** * 判断目录是否存在,不存在则判断是否创建成功 * * @param file 文件 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败 */ public static boolean createOrExistsDir(File file) { // 如果存在,是目录则返回true,是文件则返回false,不存在则返回是否创建成功 return file != null && (file.exists() ? file.isDirectory() : file.mkdirs()); } /** * 判断文件是否存在,不存在则判断是否创建成功 * * @param filePath 文件路径 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败 */ public static boolean createOrExistsFile(String filePath) { return createOrExistsFile(getFileByPath(filePath)); } /** * 判断文件是否存在,不存在则判断是否创建成功 * * @param file 文件 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败 */ public static boolean createOrExistsFile(File file) { if (file == null) return false; // 如果存在,是文件则返回true,是目录则返回false if (file.exists()) return file.isFile(); if (!createOrExistsDir(file.getParentFile())) return false; try { return file.createNewFile(); } catch (IOException e) { e.printStackTrace(); return false; } } /** * 判断文件是否存在,存在则在创建之前删除 * * @param filePath 文件路径 * @return {@code true}: 创建成功<br>{@code false}: 创建失败 */ public static boolean createFileByDeleteOldFile(String filePath) { return createFileByDeleteOldFile(getFileByPath(filePath)); } /** * 判断文件是否存在,存在则在创建之前删除 * * @param file 文件 * @return {@code true}: 创建成功<br>{@code false}: 创建失败 */ public static boolean createFileByDeleteOldFile(File file) { if (file == null) return false; // 文件存在并且删除失败返回false if (file.exists() && file.isFile() && !file.delete()) return false; // 创建目录失败返回false if (!createOrExistsDir(file.getParentFile())) return false; try { return file.createNewFile(); } catch (IOException e) { e.printStackTrace(); return false; } } /** * 复制或移动目录 * * @param srcDirPath 源目录路径 * @param destDirPath 目标目录路径 * @param isMove 是否移动 * @return {@code true}: 复制或移动成功<br>{@code false}: 复制或移动失败 */ public static boolean copyOrMoveDir(String srcDirPath, String destDirPath, boolean isMove) { return copyOrMoveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath), isMove); } /** * 复制或移动目录 * * @param srcDir 源目录 * @param destDir 目标目录 * @param isMove 是否移动 * @return {@code true}: 复制或移动成功<br>{@code false}: 复制或移动失败 */ public static boolean copyOrMoveDir(File srcDir, File destDir, boolean isMove) { if (srcDir == null || destDir == null) return false; // 如果目标目录在源目录中则返回false,看不懂的话好好想想递归怎么结束 // srcPath : F:\\MyGithub\\AndroidUtilCode\\utilcode\\src\\test\\res // destPath: F:\\MyGithub\\AndroidUtilCode\\utilcode\\src\\test\\res1 // 为防止以上这种情况出现出现误判,须分别在后面加个路径分隔符 String srcPath = srcDir.getPath() + File.separator; String destPath = destDir.getPath() + File.separator; if (destPath.contains(srcPath)) return false; // 源文件不存在或者不是目录则返回false if (!srcDir.exists() || !srcDir.isDirectory()) return false; // 目标目录不存在返回false if (!createOrExistsDir(destDir)) return false; File[] files = srcDir.listFiles(); for (File file : files) { File oneDestFile = new File(destPath + file.getName()); if (file.isFile()) { // 如果操作失败返回false if (!copyOrMoveFile(file, oneDestFile, isMove)) return false; } else if (file.isDirectory()) { // 如果操作失败返回false if (!copyOrMoveDir(file, oneDestFile, isMove)) return false; } } return !isMove || deleteDir(srcDir); } /** * 复制或移动文件 * * @param srcFilePath 源文件路径 * @param destFilePath 目标文件路径 * @param isMove 是否移动 * @return {@code true}: 复制或移动成功<br>{@code false}: 复制或移动失败 */ public static boolean copyOrMoveFile(String srcFilePath, String destFilePath, boolean isMove) { return copyOrMoveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), isMove); } /** * 复制或移动文件 * * @param srcFile 源文件 * @param destFile 目标文件 * @param isMove 是否移动 * @return {@code true}: 复制或移动成功<br>{@code false}: 复制或移动失败 */ public static boolean copyOrMoveFile(File srcFile, File destFile, boolean isMove) { if (srcFile == null || destFile == null) return false; // 源文件不存在或者不是文件则返回false if (!srcFile.exists() || !srcFile.isFile()) return false; // 目标文件存在且是文件则返回false if (destFile.exists() && destFile.isFile()) return false; // 目标目录不存在返回false if (!createOrExistsDir(destFile.getParentFile())) return false; try { return writeFileFromIS(destFile, new FileInputStream(srcFile), false) && !(isMove && !deleteFile(srcFile)); } catch (FileNotFoundException e) { e.printStackTrace(); return false; } } /** * 复制目录 * * @param srcDirPath 源目录路径 * @param destDirPath 目标目录路径 * @return {@code true}: 复制成功<br>{@code false}: 复制失败 */ public static boolean copyDir(String srcDirPath, String destDirPath) { return copyDir(getFileByPath(srcDirPath), getFileByPath(destDirPath)); } /** * 复制目录 * * @param srcDir 源目录 * @param destDir 目标目录 * @return {@code true}: 复制成功<br>{@code false}: 复制失败 */ public static boolean copyDir(File srcDir, File destDir) { return copyOrMoveDir(srcDir, destDir, false); } /** * 复制文件 * * @param srcFilePath 源文件路径 * @param destFilePath 目标文件路径 * @return {@code true}: 复制成功<br>{@code false}: 复制失败 */ public static boolean copyFile(String srcFilePath, String destFilePath) { return copyFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), false); } /** * 复制文件 * * @param srcFile 源文件 * @param destFile 目标文件 * @return {@code true}: 复制成功<br>{@code false}: 复制失败 */ public static boolean copyFile(File srcFile, File destFile, boolean isCopy) { return copyOrMoveFile(srcFile, destFile, false); } /** * 移动目录 * * @param srcDirPath 源目录路径 * @param destDirPath 目标目录路径 * @return {@code true}: 移动成功<br>{@code false}: 移动失败 */ public static boolean moveDir(String srcDirPath, String destDirPath) { return moveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath)); } /** * 移动目录 * * @param srcDir 源目录 * @param destDir 目标目录 * @return {@code true}: 移动成功<br>{@code false}: 移动失败 */ public static boolean moveDir(File srcDir, File destDir) { return copyOrMoveDir(srcDir, destDir, true); } /** * 移动文件 * * @param srcFilePath 源文件路径 * @param destFilePath 目标文件路径 * @return {@code true}: 移动成功<br>{@code false}: 移动失败 */ public static boolean moveFile(String srcFilePath, String destFilePath) { return moveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath)); } /** * 移动文件 * * @param srcFile 源文件 * @param destFile 目标文件 * @return {@code true}: 移动成功<br>{@code false}: 移动失败 */ public static boolean moveFile(File srcFile, File destFile) { return copyOrMoveFile(srcFile, destFile, true); } /** * 删除目录 * * @param dirPath 目录路径 * @return {@code true}: 删除成功<br>{@code false}: 删除失败 */ public static boolean deleteDir(String dirPath) { return deleteDir(getFileByPath(dirPath)); } /** * 删除目录 * * @param dir 目录 * @return {@code true}: 删除成功<br>{@code false}: 删除失败 */ public static boolean deleteDir(File dir) { if (dir == null) return false; // 目录不存在返回true if (!dir.exists()) return true; // 不是目录返回false if (!dir.isDirectory()) return false; // 现在文件存在且是文件夹 File[] files = dir.listFiles(); for (File file : files) { if (file.isFile()) { if (!deleteFile(file)) return false; } else if (file.isDirectory()) { if (!deleteDir(file)) return false; } } return dir.delete(); } /** * 删除文件 * * @param srcFilePath 文件路径 * @return {@code true}: 删除成功<br>{@code false}: 删除失败 */ public static boolean deleteFile(String srcFilePath) { return deleteFile(getFileByPath(srcFilePath)); } /** * 删除文件 * * @param file 文件 * @return {@code true}: 删除成功<br>{@code false}: 删除失败 */ public static boolean deleteFile(File file) { return file != null && (!file.exists() || file.isFile() && file.delete()); } /** * 获取目录下所有文件 * * @param dirPath 目录路径 * @param isRecursive 是否递归进子目录 * @return 文件链表 */ public static List<File> listFilesInDir(String dirPath, boolean isRecursive) { return listFilesInDir(getFileByPath(dirPath), isRecursive); } /** * 获取目录下所有文件 * * @param dir 目录 * @param isRecursive 是否递归进子目录 * @return 文件链表 */ public static List<File> listFilesInDir(File dir, boolean isRecursive) { if (isRecursive) return listFilesInDir(dir); if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); Collections.addAll(list, dir.listFiles()); return list; } /** * 获取目录下所有文件包括子目录 * * @param dirPath 目录路径 * @return 文件链表 */ public static List<File> listFilesInDir(String dirPath) { return listFilesInDir(getFileByPath(dirPath)); } /** * 获取目录下所有文件包括子目录 * * @param dir 目录 * @return 文件链表 */ public static List<File> listFilesInDir(File dir) { if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); for (File file : files) { list.add(file); if (file.isDirectory()) { list.addAll(listFilesInDir(file)); } } return list; } /** * 获取目录下所有后缀名为suffix的文件 * <p>大小写忽略</p> * * @param dirPath 目录路径 * @param suffix 后缀名 * @param isRecursive 是否递归进子目录 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(String dirPath, String suffix, boolean isRecursive) { return listFilesInDirWithFilter(getFileByPath(dirPath), suffix, isRecursive); } /** * 获取目录下所有后缀名为suffix的文件 * <p>大小写忽略</p> * * @param dir 目录 * @param suffix 后缀名 * @param isRecursive 是否递归进子目录 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(File dir, String suffix, boolean isRecursive) { if (isRecursive) return listFilesInDirWithFilter(dir, suffix); if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); for (File file : files) { if (file.getName().toUpperCase().endsWith(suffix.toUpperCase())) { list.add(file); } } return list; } /** * 获取目录下所有后缀名为suffix的文件包括子目录 * <p>大小写忽略</p> * * @param dirPath 目录路径 * @param suffix 后缀名 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(String dirPath, String suffix) { return listFilesInDirWithFilter(getFileByPath(dirPath), suffix); } /** * 获取目录下所有后缀名为suffix的文件包括子目录 * <p>大小写忽略</p> * * @param dir 目录 * @param suffix 后缀名 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(File dir, String suffix) { if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); for (File file : files) { if (file.getName().toUpperCase().endsWith(suffix.toUpperCase())) { list.add(file); } if (file.isDirectory()) { list.addAll(listFilesInDirWithFilter(file, suffix)); } } return list; } /** * 获取目录下所有符合filter的文件 * * @param dirPath 目录路径 * @param filter 过滤器 * @param isRecursive 是否递归进子目录 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(String dirPath, FilenameFilter filter, boolean isRecursive) { return listFilesInDirWithFilter(getFileByPath(dirPath), filter, isRecursive); } /** * 获取目录下所有符合filter的文件 * * @param dir 目录 * @param filter 过滤器 * @param isRecursive 是否递归进子目录 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(File dir, FilenameFilter filter, boolean isRecursive) { if (isRecursive) return listFilesInDirWithFilter(dir, filter); if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); for (File file : files) { if (filter.accept(file.getParentFile(), file.getName())) { list.add(file); } } return list; } /** * 获取目录下所有符合filter的文件包括子目录 * * @param dirPath 目录路径 * @param filter 过滤器 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(String dirPath, FilenameFilter filter) { return listFilesInDirWithFilter(getFileByPath(dirPath), filter); } /** * 获取目录下所有符合filter的文件包括子目录 * * @param dir 目录 * @param filter 过滤器 * @return 文件链表 */ public static List<File> listFilesInDirWithFilter(File dir, FilenameFilter filter) { if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); for (File file : files) { if (filter.accept(file.getParentFile(), file.getName())) { list.add(file); } if (file.isDirectory()) { list.addAll(listFilesInDirWithFilter(file, filter)); } } return list; } /** * 获取目录下指定文件名的文件包括子目录 * <p>大小写忽略</p> * * @param dirPath 目录路径 * @param fileName 文件名 * @return 文件链表 */ public static List<File> searchFileInDir(String dirPath, String fileName) { return searchFileInDir(getFileByPath(dirPath), fileName); } /** * 获取目录下指定文件名的文件包括子目录 * <p>大小写忽略</p> * * @param dir 目录 * @param fileName 文件名 * @return 文件链表 */ public static List<File> searchFileInDir(File dir, String fileName) { if (dir == null || !isDir(dir)) return null; List<File> list = new ArrayList<>(); File[] files = dir.listFiles(); for (File file : files) { if (file.getName().toUpperCase().equals(fileName.toUpperCase())) { list.add(file); } if (file.isDirectory()) { list.addAll(listFilesInDirWithFilter(file, fileName)); } } return list; } /** * 将输入流写入文件 * * @param filePath 路径 * @param is 输入流 * @param append 是否追加在文件末 * @return {@code true}: 写入成功<br>{@code false}: 写入失败 */ public static boolean writeFileFromIS(String filePath, InputStream is, boolean append) { return writeFileFromIS(getFileByPath(filePath), is, append); } /** * 将输入流写入文件 * * @param file 文件 * @param is 输入流 * @param append 是否追加在文件末 * @return {@code true}: 写入成功<br>{@code false}: 写入失败 */ public static boolean writeFileFromIS(File file, InputStream is, boolean append) { if (file == null || is == null) return false; if (!createOrExistsFile(file)) return false; OutputStream os = null; try { os = new BufferedOutputStream(new FileOutputStream(file, append)); byte data[] = new byte[KB]; int len; while ((len = is.read(data, 0, KB)) != -1) { os.write(data, 0, len); } return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { closeIO(is, os); } } /** * 将字符串写入文件 * * @param filePath 文件路径 * @param content 写入内容 * @param append 是否追加在文件末 * @return {@code true}: 写入成功<br>{@code false}: 写入失败 */ public static boolean writeFileFromString(String filePath, String content, boolean append) { return writeFileFromString(getFileByPath(filePath), content, append); } /** * 将字符串写入文件 * * @param file 文件 * @param content 写入内容 * @param append 是否追加在文件末 * @return {@code true}: 写入成功<br>{@code false}: 写入失败 */ public static boolean writeFileFromString(File file, String content, boolean append) { if (file == null || content == null) return false; if (!createOrExistsFile(file)) return false; FileWriter fileWriter = null; try { fileWriter = new FileWriter(file, append); fileWriter.write(content); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { closeIO(fileWriter); } } /** * 指定编码按行读取文件到List * * @param filePath 文件路径 * @param charsetName 编码格式 * @return 文件行链表 */ public static List<String> readFile2List(String filePath, String charsetName) { return readFile2List(getFileByPath(filePath), charsetName); } /** * 指定编码按行读取文件到List * * @param file 文件 * @param charsetName 编码格式 * @return 文件行链表 */ public static List<String> readFile2List(File file, String charsetName) { return readFile2List(file, 0, 0x7FFFFFFF, charsetName); } /** * 指定编码按行读取文件到List * * @param filePath 文件路径 * @param st 需要读取的开始行数 * @param end 需要读取的结束行数 * @param charsetName 编码格式 * @return 包含制定行的list */ public static List<String> readFile2List(String filePath, int st, int end, String charsetName) { return readFile2List(getFileByPath(filePath), st, end, charsetName); } /** * 指定编码按行读取文件到List * * @param file 文件 * @param st 需要读取的开始行数 * @param end 需要读取的结束行数 * @param charsetName 编码格式 * @return 包含从start行到end行的list */ public static List<String> readFile2List(File file, int st, int end, String charsetName) { if (file == null) return null; if (st > end) return null; BufferedReader reader = null; try { String line; int curLine = 1; List<String> list = new ArrayList<>(); if (RxDataTool.isNullString(charsetName)) { reader = new BufferedReader(new FileReader(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 { closeIO(reader); } } /** * 指定编码按行读取文件到字符串中 * * @param filePath 文件路径 * @param charsetName 编码格式 * @return 字符串 */ public static String readFile2String(String filePath, String charsetName) { return readFile2String(getFileByPath(filePath), charsetName); } /** * 指定编码按行读取文件到字符串中 * * @param file 文件 * @param charsetName 编码格式 * @return 字符串 */ public static String readFile2String(File file, String charsetName) { if (file == null) return null; BufferedReader reader = null; try { StringBuilder sb = new StringBuilder(); if (RxDataTool.isNullString(charsetName)) { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); } else { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName)); } String line; while ((line = reader.readLine()) != null) { sb.append(line).append("\r\n");// windows系统换行为\r\n,Linux为\n } // 要去除最后的换行符 return sb.delete(sb.length() - 2, sb.length()).toString(); } catch (IOException e) { e.printStackTrace(); return null; } finally { closeIO(reader); } } /** * 指定编码按行读取文件到字符数组中 * * @param filePath 文件路径 * @return StringBuilder对象 */ public static byte[] readFile2Bytes(String filePath) { return readFile2Bytes(getFileByPath(filePath)); } /** * 指定编码按行读取文件到字符数组中 * * @param file 文件 * @return StringBuilder对象 */ public static byte[] readFile2Bytes(File file) { if (file == null) return null; try { return RxDataTool.inputStream2Bytes(new FileInputStream(file)); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } } /** * 简单获取文件编码格式 * * @param filePath 文件路径 * @return 文件编码 */ public static String getFileCharsetSimple(String filePath) { return getFileCharsetSimple(getFileByPath(filePath)); } /** * 简单获取文件编码格式 * * @param file 文件 * @return 文件编码 */ public static String getFileCharsetSimple(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 { closeIO(is); } switch (p) { case 0xefbb: return "UTF-8"; case 0xfffe: return "Unicode"; case 0xfeff: return "UTF-16BE"; default: return "GBK"; } } /** * 获取文件行数 * * @param filePath 文件路径 * @return 文件行数 */ public static int getFileLines(String filePath) { return getFileLines(getFileByPath(filePath)); } /** * 获取文件行数 * * @param file 文件 * @return 文件行数 */ public static int getFileLines(File file) { int count = 1; InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[KB]; int readChars; while ((readChars = is.read(buffer, 0, KB)) != -1) { for (int i = 0; i < readChars; ++i) { if (buffer[i] == '\n') ++count; } } } catch (IOException e) { e.printStackTrace(); } finally { closeIO(is); } return count; } /** * 获取文件大小 * * @param filePath 文件路径 * @return 文件大小 */ public static String getFileSize(String filePath) { return getFileSize(getFileByPath(filePath)); } /** * 获取文件大小 * <p>例如:getFileSize(file, RxConstTool.MB); 返回文件大小单位为MB</p> * * @param file 文件 * @return 文件大小 */ public static String getFileSize(File file) { if (!isFileExists(file)) return ""; return RxDataTool.byte2FitSize(file.length()); } /** * 获取文件的MD5校验码 * * @param filePath 文件 * @return 文件的MD5校验码 */ public static String getFileMD5(String filePath) { return getFileMD5(getFileByPath(filePath)); } /** * 获取文件的MD5校验码 * * @param file 文件 * @return 文件的MD5校验码 */ public static String getFileMD5(File file) { return RxEncryptTool.encryptMD5File2String(file); } /** * 关闭IO * * @param closeables closeable */ public static void closeIO(Closeable... closeables) { if (closeables == null) return; try { for (Closeable closeable : closeables) { if (closeable != null) { closeable.close(); } } } catch (IOException e) { e.printStackTrace(); } } /** * 获取全路径中的最长目录 * * @param file 文件 * @return filePath最长目录 */ public static String getDirName(File file) { if (file == null) return null; return getDirName(file.getPath()); } /** * 获取全路径中的最长目录 * * @param filePath 文件路径 * @return filePath最长目录 */ public static String getDirName(String filePath) { if (RxDataTool.isNullString(filePath)) return filePath; int lastSep = filePath.lastIndexOf(File.separator); return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1); } /** * 获取全路径中的文件名 * * @param file 文件 * @return 文件名 */ public static String getFileName(File file) { if (file == null) return null; return getFileName(file.getPath()); } /** * 获取全路径中的文件名 * * @param filePath 文件路径 * @return 文件名 */ public static String getFileName(String filePath) { if (RxDataTool.isNullString(filePath)) return filePath; int lastSep = filePath.lastIndexOf(File.separator); return lastSep == -1 ? filePath : filePath.substring(lastSep + 1); } /** * 获取全路径中的不带拓展名的文件名 * * @param file 文件 * @return 不带拓展名的文件名 */ public static String getFileNameNoExtension(File file) { if (file == null) return null; return getFileNameNoExtension(file.getPath()); } /** * 获取全路径中的不带拓展名的文件名 * * @param filePath 文件路径 * @return 不带拓展名的文件名 */ public static String getFileNameNoExtension(String filePath) { if (RxDataTool.isNullString(filePath)) return filePath; 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); } /** * 获取全路径中的文件拓展名 * * @param file 文件 * @return 文件拓展名 */ public static String getFileExtension(File file) { if (file == null) return null; return getFileExtension(file.getPath()); } /** * 获取全路径中的文件拓展名 * * @param filePath 文件路径 * @return 文件拓展名 */ public static String getFileExtension(String filePath) { if (RxDataTool.isNullString(filePath)) return filePath; int lastPoi = filePath.lastIndexOf('.'); int lastSep = filePath.lastIndexOf(File.separator); if (lastPoi == -1 || lastSep >= lastPoi) return ""; return filePath.substring(lastPoi); } /** * 将文件转换成uri(支持7.0) * @param mContext * @param file * @return */ public static Uri getUriForFile(Context mContext, File file) { Uri fileUri = null; if (Build.VERSION.SDK_INT >= 24) { fileUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".fileprovider", file); } else { fileUri = Uri.fromFile(file); } return fileUri; } /** * 将图片文件转换成uri * * @param context * @param imageFile * @return */ public static Uri getImageContentUri(Context context, File imageFile) { String filePath = imageFile.getAbsolutePath(); Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ", new String[]{filePath}, null); if (cursor != null && cursor.moveToFirst()) { int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); Uri baseUri = Uri.parse("content://media/external/images/media"); return Uri.withAppendedPath(baseUri, "" + id); } else { if (imageFile.exists()) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DATA, filePath); return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } else { return null; } } } /** * 将Uri转换成File * * @param context * @param uri * @return */ public static File getFilePhotoFromUri(Activity context, Uri uri) { return new File(RxPhotoTool.getImageAbsolutePath(context, uri)); } @TargetApi(19) public static String getPathFromUri(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{ split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return ""; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; String column = MediaStore.Images.Media.DATA; String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * 安静关闭IO * * @param closeables closeable */ public static void closeIOQuietly(Closeable... closeables) { if (closeables == null) return; for (Closeable closeable : closeables) { if (closeable != null) { try { closeable.close(); } catch (IOException ignored) { } } } } public static String file2Base64(String filePath) { FileInputStream fis = null; String base64String = ""; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { fis = new FileInputStream(filePath); byte[] buffer = new byte[1024 * 100]; int count = 0; while ((count = fis.read(buffer)) != -1) { bos.write(buffer, 0, count); } fis.close(); } catch (Exception e) { e.printStackTrace(); } base64String = Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT); return base64String; } /** * 传入文件名以及字符串, 将字符串信息保存到文件中 * * @param strFilePath * @param strBuffer */ public void TextToFile(final String strFilePath, final String strBuffer) { FileWriter fileWriter = null; try { // 创建文件对象 File fileText = new File(strFilePath); // 向文件写入对象写入信息 fileWriter = new FileWriter(fileText); // 写文件 fileWriter.write(strBuffer); // 关闭 } catch (IOException e) { e.printStackTrace(); } finally { try { fileWriter.flush(); fileWriter.close(); } catch (IOException ex) { ex.printStackTrace(); } } } /** * 以行为单位读取文件,常用于读面向行的格式化文件 */ public void readFileByLines(String fileName) { File file = new File(fileName); BufferedReader reader = null; try { System.out.println("以行为单位读取文件内容,一次读一整行:"); reader = new BufferedReader(new FileReader(file)); String tempString = null; int line = 1; // 一次读入一行,直到读入null为文件结束 while ((tempString = reader.readLine()) != null) { // 显示行号 System.out.println("line?????????????????????????????????? " + line + ": " + tempString); String content = tempString; line++; } reader.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } } } //----------------------------------------m3u8 ts 操作---------------------------------------------- // /** // * 获取ts文件 // * // * @param url // * @param title // * @param i // * @param dataList // * @param fileList // */ // public static void getFile(final Context context, String url, final String title, final int i, final List<TrackData> dataList, final List<File> fileList, final String duration, final File m3u8File) { // // OkHttpUtils// // .get()// // .url(url)// // .build()// // .execute(new FileCallBack(FileUtil.getDiskFileDir(context) + File.separator + title, title + i + ".ts") { // @Override // public void onError(Call call, Exception e, int id) { //// Log.d("下载", e.getMessage()); // } // // @Override // public void onResponse(File response, int id) { //// Log.d("ts下载", response.getAbsolutePath()); // fileList.add(response); // if (dataList.size() == fileList.size()) { // //FileUtil.mergeFiles(context, new File(FileUtil.getDiskFileDir(context) + File.separator + title, title + "_" + duration + ".mp4"), fileList); //// Log.d("ts下载", "下载完成"); ///* RxTool.ShowToast(context, "视频文件缓存成功,开始合并视频文件...", false);*/ // getNativeM3u(context, m3u8File, fileList); // } else { // getFile(context, dataList.get(i + 1).getUri(), title, i + 1, dataList, fileList, duration, m3u8File); // } // } // // @Override // public void inProgress(float progress, long total, int id) { // super.inProgress(progress, total, id); // } // }); // } // // /** // * 下载文件 // * // * @param url // */ // public static void getFile(String url, final String filePath, String name) { // // OkHttpUtils// // .get()// // .url(url)// // .build()// // .execute(new FileCallBack(filePath, name) { // @Override // public void onError(Call call, Exception e, int id) { // // try { //// Log.d("下载", e.getMessage()); // } catch (Exception e1) { // e1.printStackTrace(); // } // } // // @Override // public void onResponse(File response, int id) { // try { //// Log.d("下载", response.getAbsolutePath()); // } catch (Exception e) { // e.printStackTrace(); // } // } // // @Override // public void inProgress(float progress, long total, int id) { // super.inProgress(progress, total, id); // } // }); // } // // /** // * 获取m3u8列表 // * // * @param context // * @param videoParse1 // * @param vid // */ // public static void getM3U8(final Context context, final VideoParse1 videoParse1, final String vid, final String duration) { // /* final DownloadRequest downloadRequest = NoHttp.createDownloadRequest(videoParse1.getUrl().get(0).getU(), FileUtil.getDiskFileDir(getApplicationContext()), videoParse1.getTitle() + "m3u8", false, true); // downloadQueue.add(0, downloadRequest, downloadListener);*/ // /*downloadRequest.onPreResponse();*/ // OkHttpUtils// // .get()// // .url(videoParse1.getUrl().get(0).getU())// // .build()// // .execute(new FileCallBack(FileUtil.getDiskFileDir(context), videoParse1.getTitle() + "%" + vid + "%" + duration + "%m3u8") { // @Override // public void onError(Call call, Exception e, int id) { // RxTool.ShowToast(context, "下载文件清单缓冲失败...", 500); // } // // @Override // public void onBefore(Request request, int id) { // super.onBefore(request, id); // RxTool.ShowToast(context, "开始缓存...", 500); // } // // @Override // public void onResponse(File response, int id) { // try { // InputStream inputStream = new FileInputStream(response); // PlaylistParser parser = new PlaylistParser(inputStream, Format.EXT_M3U, Encoding.UTF_8); // Playlist playlist = parser.parse(); //// Log.d("下载链接", playlist.toString()); // List<String> downList = new ArrayList<String>(); // List<TrackData> dataList = playlist.getMediaPlaylist().getTracks(); // for (int j = 0; j < dataList.size(); j++) { //// float duration = dataList.get(j).getTrackInfo().duration;//时长 // downList.add(dataList.get(0).getUri()); // } // RxTool.ShowToast(context, "缓冲清单成功,开始缓存视频文件...", 500); // FileUtil.getFile(context, dataList.get(0).getUri(), vid, 0, dataList, new ArrayList<File>(), duration, response); // } catch (FileNotFoundException e) { // e.printStackTrace(); //// Log.d("下载链接", "FileNotFoundException"); // } catch (IOException e) { // e.printStackTrace(); //// Log.d("下载链接", "IOException"); // } catch (ParseException e) { // e.printStackTrace(); //// Log.d("下载链接", "ParseException"); // } catch (PlaylistException e) { // e.printStackTrace(); //// Log.d("下载链接", "PlaylistException"); // } // } // // @Override // public void inProgress(float progress, long total, int id) { // super.inProgress(progress, total, id); // } // }); // } //========================================m3u8 ts 操作==================================================