Files
EhViewer/app/src/main/java/com/hippo/yorozuya/FileUtils.java
T
2022-08-22 11:38:03 +08:00

329 lines
8.7 KiB
Java

/*
* 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.nio.charset.StandardCharsets;
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.<br/>
* 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(StandardCharsets.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;
}
}