/* * Copyright (C) 2015 Hippo Seven * * 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.hippo.yorozuya; import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Locale; public final class FileUtils { private static final char[] FORBIDDEN_FILENAME_CHARACTERS = { '\\', '/', ':', '*', '?', '"', '<', '>', '|', }; private FileUtils() { } public static boolean ensureFile(File file) { return file != null && (!file.exists() || file.isFile()); } public static boolean ensureDirectory(File file) { if (file != null) { if (file.exists()) { return file.isDirectory(); } else { return file.mkdirs(); } } else { return false; } } /** * Convert byte to human readable string.
* http://stackoverflow.com/questions/3758606/ * * @param bytes the bytes to convert * @param si si units * @return the human readable string */ public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + " B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); return String.format(Locale.US, "%.1f %sB", bytes / Math.pow(unit, exp), pre); } /** * Try to delete file, dir and it's children * * @param file the file to delete * The dir to deleted */ public static boolean delete(File file) { if (file == null) { return false; } boolean success = true; File[] files = file.listFiles(); if (files != null) { for (File f : files) { success &= delete(f); } } /* final File to = new File(file.getAbsolutePath() + System.currentTimeMillis()); if (file.renameTo(to)) { success &= to.delete(); } else success &= file.delete(); } */ success &= file.delete(); return success; } public static boolean deleteContent(File file) { if (file == null) { return false; } boolean success = true; File[] files = file.listFiles(); if (files != null) { for (File f : files) { success &= delete(f); } } return success; } /** * @return {@code null} for get exception */ @Nullable public static String read(File file) { if (file == null) { return null; } InputStream is = null; try { is = new FileInputStream(file); return IOUtils.readString(is, "utf-8"); } catch (IOException e) { e.printStackTrace(); return null; } finally { IOUtils.closeQuietly(is); } } public static boolean write(File file, String str) { if (file == null) { return false; } if (str == null) { return true; } OutputStream os = null; try { os = new FileOutputStream(file); os.write(str.getBytes("utf-8")); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { IOUtils.closeQuietly(os); } } public static String sanitizeFilename(@NonNull String filename) { // Remove forbidden_filename_characters filename = StringUtils.remove(filename, FORBIDDEN_FILENAME_CHARACTERS); // Ensure utf-8 byte count <= 255 int byteCount = 0; int length = 0; for (int len = filename.length(); length < len; length++) { char ch = filename.charAt(length); if (ch <= 0x7F) { byteCount++; } else if (ch <= 0x7FF) { byteCount += 2; } else if (Character.isHighSurrogate(ch)) { byteCount += 4; ++length; } else { byteCount += 3; } // Meet max byte count if (byteCount > 255) { filename = filename.substring(0, length); break; } } // Trim return StringUtils.trim(filename); } /** * Get extension from filename * * @param filename the complete filename * @return null for can't find extension, "" empty String for ending with . dot */ public static String getExtensionFromFilename(@Nullable String filename) { if (null == filename) { return null; } int index = filename.lastIndexOf('.'); if (index != -1) { return filename.substring(index + 1); } else { return null; } } /** * Get name from filename * * @param filename the complete filename * @return null for start with . dot */ public static String getNameFromFilename(@Nullable String filename) { if (null == filename) { return null; } int index = filename.lastIndexOf('.'); if (index != -1) { String name = filename.substring(0, index); return TextUtils.isEmpty(name) ? null : name; } else { return filename; } } /** * Create a temp file, you need to delete it by you self. * * @param parent The temp file's parent * @param extension The extension of temp file * @return The temp file or null */ @Nullable public static File createTempFile(@Nullable File parent, @Nullable String extension) { if (parent == null) { return null; } long now = System.currentTimeMillis(); for (int i = 0; i < 100; i++) { String filename = Long.toString(now + i); if (extension != null) { filename = filename + '.' + extension; } File tempFile = new File(parent, filename); if (!tempFile.exists()) { return tempFile; } } // Unbelievable return null; } /** * Create a temp dir, you need to delete it by you self. * * @param parent The temp file's parent * @return The temp dir or null */ @Nullable public static File createTempDir(@Nullable File parent) { if (parent == null) { return null; } long now = System.currentTimeMillis(); for (int i = 0; i < 100; i++) { String filename = Long.toString(now + i); File tempFile = new File(parent, filename); if (!tempFile.exists() && tempFile.mkdirs()) { return tempFile; } } // Unbelievable return null; } /** * Only support file now */ public static boolean rename(@NonNull File from, @NonNull File to) { if (!from.isFile() || to.exists()) { return false; } boolean ok = from.renameTo(to); if (ok && !from.exists() && to.isFile()) { return true; } // Copy content InputStream is = null; OutputStream os = null; try { is = new FileInputStream(from); os = new FileOutputStream(to); IOUtils.copy(is, os); ok = true; } catch (IOException e) { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); ok = false; } if (!ok) { to.delete(); return false; } // delete old one from.delete(); return true; } }