package net.dev123.commons.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FileUtil { private static final Logger logger = LoggerFactory.getLogger(FileUtil.class); private FileUtil(){} /** * The number of bytes in a kilobyte. */ public static final long ONE_KB = 1024; /** * The number of bytes in a megabyte. */ public static final long ONE_MB = ONE_KB * ONE_KB; /** * The number of bytes in a gigabyte. */ public static final long ONE_GB = ONE_KB * ONE_MB; /** * The UTF-8 character set, used to decode octets in URLs. */ private static final Charset UTF8 = Charset.forName("UTF-8"); /** * 根据文件名获取扩展名 * * @param filename * 文件名 * @return 文件扩展名 */ public static String getFileExtensionFromName(String filename) { if (filename == null) { return null; } int index = indexOfExtension(filename); if (index == -1) { return ""; } else { return filename.substring(index + 1); } } private static int indexOfExtension(String filename) { if (filename == null) { return -1; } int extensionPos = filename.lastIndexOf("."); int lastSeparator = filename.lastIndexOf("/"); return (lastSeparator > extensionPos ? -1 : extensionPos); } /** * Returns the file extension or an empty string if there is no extension. * This method is a convenience method for obtaining the extension of a url * and has undefined results for other Strings. * * @param url * @return The file extension of the given url. */ public static String getFileExtensionFromUrl(String url) { if (url != null && url.length() > 0) { int query = url.lastIndexOf('?'); if (query > 0) { url = url.substring(0, query); } int filenamePos = url.lastIndexOf('/'); String filename = 0 <= filenamePos ? url.substring(filenamePos + 1) : url; // if the filename contains special characters, we don't // consider it valid for our matching purposes: if (filename.length() > 0 && Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)]+", filename)) { int dotPos = filename.lastIndexOf('.'); if (0 <= dotPos) { return filename.substring(dotPos + 1); } } } return ""; } public static String getFileExtensionFromSource(byte[] picHeader) { String picExtendName = null; if (picHeader.length >= 2 && (picHeader[0] == 66) && (picHeader[1] == 77)) { //header bytes contains BM? picExtendName = "BMP"; } else if (picHeader.length >= 4 && (picHeader[1] == 80) && (picHeader[2] == 78) && (picHeader[3] == 71)) { //header bytes contains PNG? picExtendName = "PNG"; } else if (picHeader.length >= 6 && (picHeader[0] == 71) && (picHeader[1] == 73) && (picHeader[2] == 70) && (picHeader[3] == 56) && ((picHeader[4] == 55)||(picHeader[4] == 57)) && (picHeader[5] == 97)) { //header bytes contains GIF87a or GIF89a? picExtendName = "GIF"; } else if (picHeader.length >= 10 && (picHeader[6] == 74) && (picHeader[7] == 70) && (picHeader[8] == 73) && (picHeader[9] == 70)) { //header bytes contains JFIF? picExtendName = "JPG"; } return picExtendName; } public static boolean isGif(String filePath) { boolean isGif = false; if (StringUtil.isEmpty(filePath)) { return isGif; } File file = new File(filePath); if (file.exists() && file.isFile()) { FileInputStream fis = null; try { fis = new FileInputStream(file); StringBuilder head = new StringBuilder(""); for (int i = 0; i < 6; i++) { head.append((char) fis.read()); } if (head.indexOf("GIF") == 0) { isGif = true; } } catch (FileNotFoundException e) { logger.error("isGif", e); } catch (IOException e) { logger.error("isGif", e); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { } } } } return isGif; } public static byte[] readFileToByteArray(String filePath) { if (StringUtil.isEmpty(filePath)) { return null; } File file = new File(filePath); return readFileToByteArray(file); } public static byte[] readFileToByteArray(File file) { byte[] fileBytes = new byte[(int) file.length()]; FileInputStream fis = null; try { fis = new FileInputStream(file); int offset = 0; int count = (int) file.length(); int temp = 0; while ((temp = fis.read(fileBytes, offset, count)) > 0) { offset += temp; count -= temp; } } catch (FileNotFoundException e) { logger.error("readFile", e); } catch (IOException e) { logger.error("readFile", e); } catch (Exception e) { logger.error("readFile", e); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { logger.error("readFile", e); } } } return fileBytes; } public static FileInputStream openInputStream(File file) throws IOException { if (file.exists()) { if (file.isDirectory()) { throw new IOException("File '" + file + "' exists but is a directory"); } if (file.canRead() == false) { throw new IOException("File '" + file + "' cannot be read"); } } else { throw new FileNotFoundException("File '" + file + "' does not exist"); } return new FileInputStream(file); } public static String byteCountToDisplaySize(long size) { String displaySize; if (size / ONE_GB > 0) { displaySize = String.format("%1$.1f GB", (float)size / ONE_GB); } else if (size / ONE_MB > 0) { displaySize = String.format("%1$.1f MB", (float)size / ONE_MB); } else if (size / ONE_KB > 0) { displaySize = String.format("%1$.1f KB",(float)size / ONE_KB); } else { displaySize = String.valueOf(size) + " Bytes"; } return displaySize; } public static long sizeOf(File file) { if (!file.exists()) { throw new IllegalArgumentException(file + " does not exist"); } if (file.isDirectory()) { return sizeOfDirectory(file); } else { return file.length(); } } public static long sizeOfDirectory(File directory) { if (!directory.exists()) { String message = directory + " does not exist"; throw new IllegalArgumentException(message); } if (!directory.isDirectory()) { String message = directory + " is not a directory"; throw new IllegalArgumentException(message); } long size = 0; File[] files = directory.listFiles(); if (files == null) { // null if security restricted return 0L; } for (File file : files) { size += sizeOf(file); } return size; } public static File toFile(URL url) { if (url == null || !"file".equalsIgnoreCase(url.getProtocol())) { return null; } else { String filename = url.getFile().replace('/', File.separatorChar); filename = decodeUrl(filename); return new File(filename); } } /** * Decodes the specified URL as per RFC 3986, i.e. transforms * percent-encoded octets to characters by decoding with the UTF-8 character * set. This function is primarily intended for usage with * {@link java.net.URL} which unfortunately does not enforce proper URLs. As * such, this method will leniently accept invalid characters or malformed * percent-encoded octets and simply pass them literally through to the * result string. Except for rare edge cases, this will make unencoded URLs * pass through unaltered. * * @param url The URL to decode, may be <code>null</code>. * @return The decoded URL or <code>null</code> if the input was * <code>null</code>. */ static String decodeUrl(String url) { String decoded = url; if (url != null && url.indexOf('%') >= 0) { int n = url.length(); StringBuffer buffer = new StringBuffer(); ByteBuffer bytes = ByteBuffer.allocate(n); for (int i = 0; i < n;) { if (url.charAt(i) == '%') { try { do { byte octet = (byte) Integer.parseInt(url.substring(i + 1, i + 3), 16); bytes.put(octet); i += 3; } while (i < n && url.charAt(i) == '%'); continue; } catch (RuntimeException e) { // malformed percent-encoded octet, fall through and // append characters literally } finally { if (bytes.position() > 0) { bytes.flip(); buffer.append(UTF8.decode(bytes).toString()); bytes.clear(); } } } buffer.append(url.charAt(i++)); } decoded = buffer.toString(); } return decoded; } }