/** * Copyright 2016 JustWayward Team * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.justwayward.reader.utils; import android.content.Context; import android.os.Environment; import com.justwayward.reader.base.Constant; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.nio.channels.FileChannel; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * @author yuyh. * @date 16/4/9. */ public class FileUtils { public static String getChapterPath(String bookId, int chapter) { return Constant.PATH_TXT + bookId + File.separator + chapter + ".txt"; } public static File getChapterFile(String bookId, int chapter) { File file = new File(getChapterPath(bookId, chapter)); if (!file.exists()) createFile(file); return file; } public static File getBookDir(String bookId) { return new File(Constant.PATH_TXT + bookId); } public static File createWifiTempFile() { String src = Constant.PATH_DATA + "/" + System.currentTimeMillis(); File file = new File(src); if (!file.exists()) createFile(file); return file; } /** * 获取Wifi传书保存文件 * * @param fileName * @return */ public static File createWifiTranfesFile(String fileName) { LogUtils.i("wifi trans save " + fileName); // 取文件名作为文件夹(bookid) String absPath = Constant.PATH_TXT + "/" + fileName + "/1.txt"; File file = new File(absPath); if (!file.exists()) createFile(file); return file; } public static String getEpubFolderPath(String epubFileName) { return Constant.PATH_EPUB + "/" + epubFileName; } public static String getPathOPF(String unzipDir) { String mPathOPF = ""; try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(unzipDir + "/META-INF/container.xml"), "UTF-8")); String line; while ((line = br.readLine()) != null) { if (line.contains("full-path")) { int start = line.indexOf("full-path"); int start2 = line.indexOf('\"', start); int stop2 = line.indexOf('\"', start2 + 1); if (start2 > -1 && stop2 > start2) { mPathOPF = line.substring(start2 + 1, stop2).trim(); break; } } } br.close(); if (!mPathOPF.contains("/")) { return null; } int last = mPathOPF.lastIndexOf('/'); if (last > -1) { mPathOPF = mPathOPF.substring(0, last); } return mPathOPF; } catch (NullPointerException | IOException e) { LogUtils.e(e.toString()); } return mPathOPF; } public static boolean checkOPFInRootDirectory(String unzipDir) { String mPathOPF = ""; boolean status = false; try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(unzipDir + "/META-INF/container.xml"), "UTF-8")); String line; while ((line = br.readLine()) != null) { if (line.contains("full-path")) { int start = line.indexOf("full-path"); int start2 = line.indexOf('\"', start); int stop2 = line.indexOf('\"', start2 + 1); if (start2 > -1 && stop2 > start2) { mPathOPF = line.substring(start2 + 1, stop2).trim(); break; } } } br.close(); if (!mPathOPF.contains("/")) { status = true; } else { status = false; } } catch (NullPointerException | IOException e) { LogUtils.e(e.toString()); } return status; } public static void unzipFile(String inputZip, String destinationDirectory) throws IOException { int buffer = 2048; List<String> zipFiles = new ArrayList<>(); File sourceZipFile = new File(inputZip); File unzipDirectory = new File(destinationDirectory); createDir(unzipDirectory.getAbsolutePath()); ZipFile zipFile; zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ); Enumeration zipFileEntries = zipFile.entries(); while (zipFileEntries.hasMoreElements()) { ZipEntry entry = (ZipEntry) zipFileEntries.nextElement(); String currentEntry = entry.getName(); File destFile = new File(unzipDirectory, currentEntry); if (currentEntry.endsWith(Constant.SUFFIX_ZIP)) { zipFiles.add(destFile.getAbsolutePath()); } File destinationParent = destFile.getParentFile(); createDir(destinationParent.getAbsolutePath()); if (!entry.isDirectory()) { if (destFile != null && destFile.exists()) { LogUtils.i(destFile + "已存在"); continue; } BufferedInputStream is = new BufferedInputStream(zipFile.getInputStream(entry)); int currentByte; // buffer for writing file byte[] data = new byte[buffer]; FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, buffer); while ((currentByte = is.read(data, 0, buffer)) != -1) { dest.write(data, 0, currentByte); } dest.flush(); dest.close(); is.close(); } } zipFile.close(); for (Iterator iter = zipFiles.iterator(); iter.hasNext(); ) { String zipName = (String) iter.next(); unzipFile(zipName, destinationDirectory + File.separatorChar + zipName.substring(0, zipName.lastIndexOf(Constant.SUFFIX_ZIP))); } } /** * 读取Assets文件 * * @param fileName * @return */ public static byte[] readAssets(String fileName) { if (fileName == null || fileName.length() <= 0) { return null; } byte[] buffer = null; try { InputStream fin = AppUtils.getAppContext().getAssets().open("uploader" + fileName); int length = fin.available(); buffer = new byte[length]; fin.read(buffer); fin.close(); } catch (Exception e) { e.printStackTrace(); } finally { return buffer; } } /** * 创建根缓存目录 * * @return */ public static String createRootPath(Context context) { String cacheRootPath = ""; if (isSdCardAvailable()) { // /sdcard/Android/data/<application package>/cache cacheRootPath = context.getExternalCacheDir().getPath(); } else { // /data/data/<application package>/cache cacheRootPath = context.getCacheDir().getPath(); } return cacheRootPath; } public static boolean isSdCardAvailable() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } /** * 递归创建文件夹 * * @param dirPath * @return 创建失败返回"" */ public static String createDir(String dirPath) { try { File file = new File(dirPath); if (file.getParentFile().exists()) { LogUtils.i("----- 创建文件夹" + file.getAbsolutePath()); file.mkdir(); return file.getAbsolutePath(); } else { createDir(file.getParentFile().getAbsolutePath()); LogUtils.i("----- 创建文件夹" + file.getAbsolutePath()); file.mkdir(); } } catch (Exception e) { e.printStackTrace(); } return dirPath; } /** * 递归创建文件夹 * * @param file * @return 创建失败返回"" */ public static String createFile(File file) { try { if (file.getParentFile().exists()) { LogUtils.i("----- 创建文件" + file.getAbsolutePath()); file.createNewFile(); return file.getAbsolutePath(); } else { createDir(file.getParentFile().getAbsolutePath()); file.createNewFile(); LogUtils.i("----- 创建文件" + file.getAbsolutePath()); } } catch (Exception e) { e.printStackTrace(); } return ""; } /** * 将内容写入文件 * * @param filePath eg:/mnt/sdcard/demo.txt * @param content 内容 * @param isAppend 是否追加 */ public static void writeFile(String filePath, String content, boolean isAppend) { LogUtils.i("save:" + filePath); try { FileOutputStream fout = new FileOutputStream(filePath, isAppend); byte[] bytes = content.getBytes(); fout.write(bytes); fout.close(); } catch (Exception e) { e.printStackTrace(); } } public static void writeFile(String filePathAndName, String fileContent) { try { OutputStream outstream = new FileOutputStream(filePathAndName); OutputStreamWriter out = new OutputStreamWriter(outstream); out.write(fileContent); out.close(); } catch (java.io.IOException e) { e.printStackTrace(); } } /** * 获取Raw下的文件内容 * * @param context * @param resId * @return 文件内容 */ public static String getFileFromRaw(Context context, int resId) { if (context == null) { return null; } StringBuilder s = new StringBuilder(); try { InputStreamReader in = new InputStreamReader(context.getResources().openRawResource(resId)); BufferedReader br = new BufferedReader(in); String line; while ((line = br.readLine()) != null) { s.append(line); } return s.toString(); } catch (IOException e) { e.printStackTrace(); return null; } } public static byte[] getBytesFromFile(File f) { if (f == null) { return null; } try { FileInputStream stream = new FileInputStream(f); ByteArrayOutputStream out = new ByteArrayOutputStream(1000); byte[] b = new byte[1000]; for (int n; (n = stream.read(b)) != -1; ) { out.write(b, 0, n); } stream.close(); out.close(); return out.toByteArray(); } catch (IOException e) { } return null; } /** * 文件拷贝 * * @param src 源文件 * @param desc 目的文件 */ public static void fileChannelCopy(File src, File desc) { //createFile(src); createFile(desc); FileInputStream fi = null; FileOutputStream fo = null; try { fi = new FileInputStream(src); fo = new FileOutputStream(desc); FileChannel in = fi.getChannel();//得到对应的文件通道 FileChannel out = fo.getChannel();//得到对应的文件通道 in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道 } catch (IOException e) { e.printStackTrace(); } finally { try { if (fo != null) fo.close(); if (fi != null) fi.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 转换文件大小 * * @param fileLen 单位B * @return */ public static String formatFileSizeToString(long fileLen) { DecimalFormat df = new DecimalFormat("0.00"); String fileSizeString = ""; if (fileLen < 1024) { fileSizeString = df.format((double) fileLen) + "B"; } else if (fileLen < 1048576) { fileSizeString = df.format((double) fileLen / 1024) + "K"; } else if (fileLen < 1073741824) { fileSizeString = df.format((double) fileLen / 1048576) + "M"; } else { fileSizeString = df.format((double) fileLen / 1073741824) + "G"; } return fileSizeString; } /** * 删除指定文件 * * @param file * @return * @throws IOException */ public static boolean deleteFile(File file) throws IOException { return deleteFileOrDirectory(file); } /** * 删除指定文件,如果是文件夹,则递归删除 * * @param file * @return * @throws IOException */ public static boolean deleteFileOrDirectory(File file) throws IOException { try { if (file != null && file.isFile()) { return file.delete(); } if (file != null && file.isDirectory()) { File[] childFiles = file.listFiles(); // 删除空文件夹 if (childFiles == null || childFiles.length == 0) { return file.delete(); } // 递归删除文件夹下的子文件 for (int i = 0; i < childFiles.length; i++) { deleteFileOrDirectory(childFiles[i]); } return file.delete(); } } catch (Exception e) { e.printStackTrace(); } return false; } /** * 获取文件夹大小 * * @return * @throws Exception */ public static long getFolderSize(String dir) throws Exception { File file = new File(dir); long size = 0; try { File[] fileList = file.listFiles(); for (int i = 0; i < fileList.length; i++) { // 如果下面还有文件 if (fileList[i].isDirectory()) { size = size + getFolderSize(fileList[i].getAbsolutePath()); } else { size = size + fileList[i].length(); } } } catch (Exception e) { e.printStackTrace(); } return size; } /*** * 获取文件扩展名 * * @param filename 文件名 * @return */ public static String getExtensionName(String filename) { if ((filename != null) && (filename.length() > 0)) { int dot = filename.lastIndexOf('.'); if ((dot > -1) && (dot < (filename.length() - 1))) { return filename.substring(dot + 1); } } return filename; } /** * 获取文件内容 * * @param path * @return */ public static String getFileOutputString(String path, String charset) { try { File file = new File(path); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset), 8192); StringBuilder sb = new StringBuilder(); String line = null; while ((line = bufferedReader.readLine()) != null) { sb.append("\n").append(line); } bufferedReader.close(); return sb.toString(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 递归获取所有文件 * * @param root * @param ext 指定扩展名 */ private synchronized void getAllFiles(File root, String ext) { List<File> list = new ArrayList<>(); File files[] = root.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { getAllFiles(f, ext); } else { if (f.getName().endsWith(ext) && f.length() > 50) list.add(f); } } } } public static String getCharset(String fileName) { BufferedInputStream bis = null; String charset = "GBK"; byte[] first3Bytes = new byte[3]; try { boolean checked = false; bis = new BufferedInputStream(new FileInputStream(fileName)); bis.mark(0); int read = bis.read(first3Bytes, 0, 3); if (read == -1) return charset; if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) { charset = "UTF-16LE"; checked = true; } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) { charset = "UTF-16BE"; checked = true; } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF) { charset = "UTF-8"; checked = true; } bis.mark(0); if (!checked) { while ((read = bis.read()) != -1) { if (read >= 0xF0) break; if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK break; if (0xC0 <= read && read <= 0xDF) { read = bis.read(); if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF) // (0x80 - 0xBF),也可能在GB编码内 continue; else break; } else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错,但是几率较小 read = bis.read(); if (0x80 <= read && read <= 0xBF) { read = bis.read(); if (0x80 <= read && read <= 0xBF) { charset = "UTF-8"; break; } else break; } else break; } } } } catch (Exception e) { e.printStackTrace(); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } } return charset; } public static String getCharset1(String fileName) throws IOException { BufferedInputStream bin = new BufferedInputStream(new FileInputStream(fileName)); int p = (bin.read() << 8) + bin.read(); String code; switch (p) { case 0xefbb: code = "UTF-8"; break; case 0xfffe: code = "Unicode"; break; case 0xfeff: code = "UTF-16BE"; break; default: code = "GBK"; } return code; } public static void saveWifiTxt(String src, String desc) { byte[] LINE_END = "\n".getBytes(); try { InputStreamReader isr = new InputStreamReader(new FileInputStream(src), getCharset(src)); BufferedReader br = new BufferedReader(isr); FileOutputStream fout = new FileOutputStream(desc, true); String temp; while ((temp = br.readLine()) != null) { byte[] bytes = temp.getBytes(); fout.write(bytes); fout.write(LINE_END); } br.close(); fout.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }