public class FileUtils {
private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
/**
* 判断目录是否存在,不存在则判断是否创建成功
*
* @param dirPath 目录路径
* @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
*/
public static boolean createOrExistsDir(String dirPath) {
if (isSpace(dirPath)) {
return false;
} else {
File path = new File(dirPath);
return path != null && (path.exists() ? path.isDirectory() : path.mkdirs());
}
}
/**
* 判断文件是否存在,不存在则判断是否创建成功
*
* @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().getAbsolutePath())) {
return false;
}
try {
return file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 用于判断指定字符是否为空白字符,空白符包含:空格、tab键、换行符。
*
* @param s
* @return
*/
private static boolean isSpace(String s) {
if (s == null) {
return true;
}
for (int i = 0, len = s.length(); i < len; ++i) {
if (!Character.isWhitespace(s.charAt(i))) {
return false;
}
}
return true;
}
public static boolean copyFile(File srcFile, File destFile) {
return copyOrMoveFile(srcFile,destFile,false);
}
public static boolean moveFile(File srcFile, File destFile) {
return copyOrMoveFile(srcFile,destFile,true);
}
/**
* 获取文件的MD5校验码
*
* @param filePath 文件路径
* @return 文件的MD5校验码
*/
public static String getFileMD5ToString(String filePath) {
File file = isSpace(filePath) ? null : new File(filePath);
return getMd5ByFile(file);
}
/**
* 获取文件的MD5校验码
*
* @param file 文件
* @return 文件的MD5校验码
*/
public static String getFileMD5ToString(File file) {
return bytes2HexString(getFileMD5(file));
}
/**
* 获取文件的MD5校验码
*
* @param file 文件
* @return 文件的MD5校验码
*/
public static byte[] getFileMD5(File file) {
if (file == null) {
return null;
}
DigestInputStream dis = null;
try {
FileInputStream fis = new FileInputStream(file);
MessageDigest md = MessageDigest.getInstance("MD5");
dis = new DigestInputStream(fis, md);
byte[] buffer = new byte[1024 * 256];
while (true) {
if (!(dis.read(buffer) > 0)) {
break;
}
}
md = dis.getMessageDigest();
return md.digest();
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
} finally {
closeIO(dis);
}
return null;
}
public static String getMd5ByFile(File file) {
FileInputStream fis = null;
StringBuffer buf = new StringBuffer();
try {
MessageDigest md = MessageDigest.getInstance("MD5");
fis = new FileInputStream(file);
byte[] buffer = new byte[1024 * 256];
int length = -1;
// Trace.d(logTag, "getFileMD5, GenMd5 start");
long s = System.currentTimeMillis();
if (fis == null || md == null) {
return null;
}
while ((length = fis.read(buffer)) != -1) {
md.update(buffer, 0, length);
}
byte[] bytes = md.digest();
if (bytes == null) {
return null;
}
for (int i = 0; i < bytes.length; i++) {
String md5s = Integer.toHexString(bytes[i] & 0xff);
if (md5s == null || buf == null) {
return null;
}
if (md5s.length() == 1) {
buf.append("0");
}
buf.append(md5s);
}
// Trace.d(logTag, "getFileMD5, GenMd5 success! spend the time: "+ (System.currentTimeMillis() - s) + "ms");
String value = buf.toString();
int fix_num = 32 - value.length();
for (int i = 0; i < fix_num; i++) {
value = "0" + value;
}
return value;
} catch (Exception ex) {
Trace.d("FileUtil", "getFileMD5, Exception " + ex.toString());
ex.printStackTrace();
return null;
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* byteArr转hexString
* <p>例如:</p>
* bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8
*
* @param bytes 字节数组
* @return 16进制大写字符串
*/
private static String bytes2HexString(byte[] bytes) {
if (bytes == null) {
return null;
}
int len = bytes.length;
if (len <= 0) {
return null;
}
char[] ret = new char[len << 1];
for (int i = 0, j = 0; i < len; i++) {
ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f];
ret[j++] = hexDigits[bytes[i] & 0x0f];
}
return new String(ret);
}
/**
* 复制或移动文件
*
* @param srcFile 源文件
* @param destFile 目标文件
* @param isMove 是否移动
* @return {@code true}: 复制或移动成功<br>{@code false}: 复制或移动失败
*/
private 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().getAbsolutePath())) {
return false;
}
try {
return writeFileFromIS(destFile, new FileInputStream(srcFile), false)
&& !(isMove && !deleteFile(srcFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
}
/**
* 将输入流写入文件
*
* @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[1024];
int len;
while ((len = is.read(data, 0, 1024)) != -1) {
os.write(data, 0, len);
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
closeIO(is, os);
}
}
public static void closeIO(Closeable... closeables) {
if (closeables == null) {
return;
}
for (Closeable closeable : closeables) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 删除文件
*
* @param file 文件
* @return {@code true}: 删除成功<br>{@code false}: 删除失败
*/
public static boolean deleteFile(File file) {
return file != null && (!file.exists() || file.isFile() && file.delete());
}
public static boolean deleteDirectory(String sPath) {
//如果sPath不以文件分隔符结尾,自动添加文件分隔符
if (!sPath.endsWith(File.separator)) {
sPath = sPath + File.separator;
}
File dirFile = new File(sPath);
//如果dir对应的文件不存在,或者不是一个目录,则退出
if (!dirFile.exists() || !dirFile.isDirectory()) {
return false;
}
boolean flag = true;
//删除文件夹下的所有文件(包括子目录)
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
//删除子文件
if (files[i].isFile()) {
flag = deleteFile(new File(files[i].getAbsolutePath()));
if (!flag) break;
} //删除子目录
else {
flag = deleteDirectory(files[i].getAbsolutePath());
if (!flag) break;
}
}
if (!flag) return false;
//删除当前目录
if (dirFile.delete()) {
return true;
} else {
return false;
}
}
/**
* 返回byte的数据大小对应的文本
*
* @param size
* @return
*/
public static String getDataSize(long size) {
if (size <= 0) {
return "";
}
DecimalFormat formater = new DecimalFormat("####.00");
if (size < 1024) {
return size + "bytes";
} else if (size < 1024 * 1024) {
float kbsize = size / 1024f;
return formater.format(kbsize) + "KB";
} else if (size < 1024 * 1024 * 1024) {
float mbsize = size / 1024f / 1024f;
return formater.format(mbsize) + "MB";
} else if (size < 1024 * 1024 * 1024 * 1024) {
float gbsize = size / 1024f / 1024f / 1024f;
return formater.format(gbsize) + "GB";
} else {
return "size: error";
}
}
/**
* 保留文件名及后缀
*/
public static String getFileNameWithSuffix(String pathandname) {
int start = pathandname.lastIndexOf("/");
if (start != -1 ) {
return pathandname.substring(start + 1);
} else {
return null;
}
}
}