工具类

import com.google.common.collect.Lists;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class FileUtil {


/**
* 删除
*
* @param dir
*/
public static void deleteAll(File dir) {

if (dir.isFile()) {
ApiLogger.info(String.format("delete file , %s , result:%s", dir, dir.delete()));
return;

} else {
File[] files = dir.listFiles();
for (File file : files) {

deleteAll(file);
}
}
ApiLogger.info(String.format("delete dir , %s , result:%s", dir, dir.delete()));
}


/**
* 将byte数组写入文件
*
* @param path
* @param content
* @throws IOException
*/
public static void writeFile(String path, byte[] content) throws IOException {
try {
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path);
fos.write(content);
fos.close();
} catch (IOException e) {
ApiLogger.error(String.format("when hls upload , writeFile , the error occured:%s", e.getMessage()), e);
}
}


/**
* 写入到文件
*
* @param file
*/
public static void writeToFile(File file, String content) throws Exception {
Writer out = null;
try {
out = new FileWriter(file);
out.write(content);
} catch (IOException e) {
ApiLogger.error(String.format("when hls upload , write to file , the error occured:%s", e.getMessage()), e);
} finally {
if (out != null) {
out.close();
}
}
}


/**
* 将文本文件中的内容读入到buffer中
*
* @param buffer buffer
* @param filePath 文件路径
* @throws IOException 异常
* @author cn.outofmemory
* @date 2013-1-7
*/
public static void readToBuffer(StringBuffer buffer, String filePath) throws IOException {
InputStream is = new FileInputStream(filePath);
String line; // 用来保存每行读取的内容
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
line = reader.readLine(); // 读取第一行
while (line != null) { // 如果 line 为空说明读完了
buffer.append(line); // 将读到的内容添加到 buffer 中
buffer.append("\n"); // 添加换行符
line = reader.readLine(); // 读取下一行
}
reader.close();
is.close();
}

/**
* 读取文本文件内容
*
* @param filePath 文件所在路径
* @return 文本内容
* @throws IOException 异常
* @author cn.outofmemory
* @date 2013-1-7
*/
public static String readFile(String filePath) throws IOException {
StringBuffer sb = new StringBuffer();
FileUtil.readToBuffer(sb, filePath);
return sb.toString();
}

/**
* 读文件
*/
public static byte[] readFileFromDiskCache(File file) {
byte[] buffer = null;

try {
buffer = new byte[(int) (file.length())];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(buffer);
bis.close();

} catch (Exception e) {
ApiLogger.error("readFileFromDiskCache error, file = " + file.getName(), e);
} finally {
}

return buffer;
}


/**
* 读文件
*/
public static byte[] readFileFromDiskCache(String filename) {
byte[] buffer = null;

try {
File file = new File(filename);

if (!file.exists())
return null;

buffer = new byte[(int) (file.length())];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(buffer);
bis.close();

} catch (Exception e) {
ApiLogger.error("readFileFromDiskCache error, file = " + filename, e);
} finally {
}

return buffer;
}

/**
* byte数组转换成16进制字符串
*
* @param src
* @return
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}

/**
* 根据文件流判断图片类型
*
* @return jpg/png/gif/bmp
*/
public static String getPicType(byte imageByte[]) {
// 读取文件的前几个字节来判断图片格式
byte[] b = new byte[4];
try {
System.arraycopy(imageByte, 0, b, 0, 4);
String type = bytesToHexString(b).toUpperCase();
if (type.contains("FFD8FF")) {
return FileTypeEnums.JPG.name();
} else if (type.contains("89504E47")) {
return FileTypeEnums.PNG.name();
} else if (type.contains("47494638")) {
return FileTypeEnums.GIF.name();
} else if (type.contains("424D")) {
return FileTypeEnums.BMP.name();
} else {
return FileTypeEnums.UNKNOWN.name();
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}

public static FileTypeInfo getFileType(byte[] bytes) {
return getFileType(bytes, 8);
}

public static FileTypeInfo getFileType(byte[] bytes, int length) {
// 读取文件的前几个字节来判断图片格式
byte[] b = new byte[length];
try {
System.arraycopy(bytes, 0, b, 0, length);
String hex = bytesToHexString(b).toUpperCase();
for (FileTypeEnums typeEnum : FileTypeEnums.values()) {
if (hex.contains(typeEnum.getHex())) {
return new FileTypeInfo(typeEnum, hex);
}
}
} catch (Exception e) {
ApiLogger.error("[getFileType] error=", e);
}
return new FileTypeInfo(FileTypeEnums.UNKNOWN, "");
}

public static boolean isAllowedImage(FileTypeEnums enums) {
return ALLOW_IMAGE.contains(enums);
}

public static boolean isAllowedImage(byte[] bytes) {
return assertAllowed(bytes, ALLOW_IMAGE);
}

public static boolean assertAllowed(byte[] bytes, FileTypeEnums... allowedExtension) {
return assertAllowed(bytes, Arrays.asList(allowedExtension));
}

/**
* 文件上传校验
*
* @param bytes 上传的文件二进制流
* @param allowedExtension 允许上传的文件后缀集合
*/
public static boolean assertAllowed(byte[] bytes, List<FileTypeEnums> allowedExtension) {
// 读取文件的前几个字节来判断图片格式
byte[] b = new byte[8];
try {
System.arraycopy(bytes, 0, b, 0, 8);
String type = bytesToHexString(b).toUpperCase();
ApiLogger.info("[assertAllowed] type=" + type);
for (FileTypeEnums typeEnum : allowedExtension) {
if (type.contains(typeEnum.getHex())) {
return true;
}
}
return false;
} catch (Exception e) {
ApiLogger.error("[assertAllowed] error=", e);
}
return false;
}

/**
* 判断MIME类型是否是允许的MIME类型
*
* @param extension
* @param allowedExtension
* @return
*/
public static boolean isAllowedExtension(String extension, String[] allowedExtension) {
for (String str : allowedExtension) {
if (str.equalsIgnoreCase(extension)) {
return true;
}
}
return false;
}

public static void main(String[] args) {

byte image1[] = readFileFromDiskCache("/Users/marion/data/image/1.jpg");
byte image2[] = readFileFromDiskCache("/Users/marion/data/image/2.jpeg");
byte image3[] = readFileFromDiskCache("/Users/marion/data/image/3.png");
byte image4[] = readFileFromDiskCache("/Users/marion/data/image/4.webp");
byte image5[] = readFileFromDiskCache("/Users/marion/data/image/5.heif");
byte image6[] = readFileFromDiskCache("/Users/marion/data/image/6.bmp");
byte image7[] = readFileFromDiskCache("/Users/marion/data/image/7.webp");

String type1 = getPicType(image1);
String type2 = getPicType(image2);
String type3 = getPicType(image3);
String type4 = getPicType(image4);
String type5 = getPicType(image5);
String type6 = getPicType(image6);
String type7 = getPicType(image7);

System.out.println("type1=" + type1); // jpg
System.out.println("type2=" + type2); // jpg
System.out.println("type3=" + type3); // png
System.out.println("type4=" + type4); // 52494646D8410000
System.out.println("type5=" + type5); // 0000001866747970
System.out.println("type6=" + type6); // bmp
System.out.println("type7=" + type7); // bmp
}

public static final List<FileTypeEnums> ALLOW_IMAGE = Arrays.asList(FileTypeEnums.JPG,
FileTypeEnums.PNG,
FileTypeEnums.GIF,
FileTypeEnums.BMP,
FileTypeEnums.WEBP
);

public enum FileTypeEnums {
/**
* hex: 二进制文件头
*/
JPG("FFD8FFE0", "jpg"),
PNG("89504E47", "png"),
GIF("47494638", "gif"),
WEBP("52494646", "webp"),
TIF("49492A00", "tif"),
BMP("424D", "bmp"),
PSD("38425053", "psd"),
XML("3C3F786D6C", "xml"),
HTML("68746D6C3E", "html"),
DOC("D0CF11E0", "doc"),
MDB("5374616E64617264204A", "mdb"),
PDF("255044462D312E", "pdf"),
DOCX("504B0304", "docx"),
RAR("52617221", "rar"),
AVI("41564920", "avi"),
HEIF("66747970", "heif"),
UNKNOWN("", "");

String hex;
String suffix;

FileTypeEnums(String hex, String suffix) {
this.hex = hex;
this.suffix = suffix;
}

public String getHex() {
return hex;
}

public String getSuffix() {
return suffix;
}
}

public static class FileTypeInfo {

private FileTypeEnums type;
private String fileHex;

public FileTypeInfo() {
}

public FileTypeInfo(FileTypeEnums type, String fileHex) {
this.type = type;
this.fileHex = fileHex;
}

public FileTypeEnums getType() {
return type;
}

public void setType(FileTypeEnums type) {
this.type = type;
}

public String getFileHex() {
return fileHex;
}

public void setFileHex(String fileHex) {
this.fileHex = fileHex;
}

}

}

参考资料


​HEIF图片格式详解 - 知乎​

​常用文件的二进制头信息​

​Convertio — 文件转换器​

​16进制转换,16进制转换文本字符串,在线16进制转换 | 在线工具​