package cn.com.wind.src.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.google.common.io.Files;
import org.springframework.util.DigestUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @Author qymeng
* @Date 2022/7/28
* @Description
*/
public class FileTools {
private static ObjectMapper mapper = new ObjectMapper();
private static Interner<String> stringPool = Interners.newWeakInterner();
static {
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
private FileTools() {
}
/**
* 读取byte[]文件内容
* @param fileBytes
* @return
*/
public static String readFile(byte[] fileBytes) {
StringBuilder stringBuilder = null;
try {
if (fileBytes!=null) {
InputStream inputStream = new ByteArrayInputStream(fileBytes);
InputStreamReader streamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(streamReader);
String line;
stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
reader.close();
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return String.valueOf(stringBuilder);
}
/**
* 写文件
* @param file
* @param fileContent
*/
public static void writeFile(File file, byte[] fileContent) {
try {
ensureParentExists(file);
Files.asByteSink(file).write(fileContent);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeFile(String filePath, byte[] fileContent){
writeFile(new File(filePath), fileContent);
}
public static void ensureParentExists(File file) throws IOException {
if (!file.exists()) {
ensureParentExists(file.getParentFile());
Files.createParentDirs(file);
}
}
/**
* byte数组转文件
*
* @param bytes
* @return
* @throws IOException
*/
public static File byteToFile(byte[] bytes, String path) {
File dir = new File(path);
if (!dir.exists() && !dir.isDirectory()) {//判断文件目录是否存在
dir.mkdirs();
}
File file = new File(path);
FileOutputStream fout = null;
try {
fout = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedOutputStream bout = new BufferedOutputStream(fout);
try {
bout.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
/**
* 删除文件或目录,若是文件,则直接删除,若是目录,则递归删除目录下的所有文件后再删除目录
*
* @param fileOrDir fileOrDir
* @return
*/
public static boolean delDirAndFile(File fileOrDir) {
if (fileOrDir.isFile()) {
return fileOrDir.delete();
}
File[] subFiles = fileOrDir.listFiles();
if (subFiles != null) {
for (File file : subFiles) {
delDirAndFile(file);
}
}
return fileOrDir.delete();
}
/**
* 寻找固定后缀名的文件
*
* @param dir
* @param suffix
* @return
*/
public static List<File> findFiles(File dir, String suffix) {
List<File> files = new ArrayList<>();
if (dir.exists()
&& dir.isDirectory()) {
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
files.addAll(findFiles(file, suffix));
} else {
if (suffix != null) {
if (file.getName().endsWith(suffix)) {
files.add(file);
}
} else {
files.add(file);
}
}
}
}
return files;
}
/**
* 得到无扩展名的文件名
*
* @param filename
* @return
*/
public static String getFileNameNoEx(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot > -1) && (dot < (filename.length()))) {
return filename.substring(0, dot);
}
}
return filename;
}
public static String calcMd5(Object source) throws IOException {
return DigestUtils.md5DigestAsHex(mapper.writeValueAsBytes(source));
}
public static <T> T deserialize(String content, Class<T> type) throws IOException {
return mapper.readValue(content, type);
}
public static <T> T deserialize(File file, Class<T> type) throws IOException {
synchronized (stringPool.intern(file.getName())) {
return mapper.readValue(file, type);
}
}
public static void serialize(File file, Object value) throws IOException {
ensureParentExists(file);
synchronized (stringPool.intern(file.getName())) {
mapper.writerWithDefaultPrettyPrinter().writeValue(file, value);
}
}
public static String charset(String path) {
String charset = "GBK";
byte[] first3Bytes = new byte[3];
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path))) {
boolean checked = false;
bis.mark(0); // 读者注: bis.mark(0);修改为 bis.mark(100);我用过这段代码,需要修改上面标出的地方。
// Wagsn注:不过暂时使用正常,遂不改之
int read = bis.read(first3Bytes, 0, 3);
if (read == -1) {
return charset; // 文件编码为 ANSI
} else if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
charset = "UTF-16LE"; // 文件编码为 Unicode
checked = true;
} else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
charset = "UTF-16BE"; // 文件编码为 Unicode big endian
checked = true;
} else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB
&& first3Bytes[2] == (byte) 0xBF) {
charset = "UTF-8"; // 文件编码为 UTF-8
checked = true;
}
bis.reset();
if (!checked) {
while ((read = bis.read()) != -1) {
if (read >= 0xF0) {
break;
}
if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK
{
break;
}
if (0xC0 <= read && read <= 0xDF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
// (0x80 - 0xBF),也可能在GB编码内
{
continue;
} else {
break;
}
} else if (0xE0 <= read && read <= 0xEF) { // 也有可能出错,但是几率较小
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
charset = "UTF-8";
break;
} else {
break;
}
} else {
break;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return charset;
}
}