0) {
- digest.update(buffer, 0, len);
- }
- String sha1 = new BigInteger(1, digest.digest()).toString(16);
- int length = 40 - sha1.length();
- if (length > 0) {
- for (int i = 0; i < length; i++) {
- sha1 = "0" + sha1;
- }
- }
- return sha1;
- } catch (NoSuchAlgorithmException e) {
- logger.severe("system algorithm error.");
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- logger.severe("file doesn't exist or is not a file");
- e.printStackTrace();
- } catch (IOException e) {
- logger.severe("The operation file is an IO exception.");
- e.printStackTrace();
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException e) {
- logger.severe("close FileInputStream IO exception.");
- }
- }
- return null;
+ return getDigest(file, "SHA-1");
}
- /***
- * 计算SHA1码
- *
- * @return String 适用于上G大的文件
- * @throws NoSuchAlgorithmException
- * */
- public static String sha1ByBigFile(File file) {
- MessageDigest messagedigest = null;
- try {
- messagedigest = MessageDigest.getInstance("SHA-1");
- FileInputStream in = new FileInputStream(file);
- FileChannel ch = in.getChannel();
- MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
- messagedigest.update(byteBuffer);
- return StrUtil.toHex(messagedigest.digest());
- } catch (NoSuchAlgorithmException e) {
- logger.severe("system algorithm error.");
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- logger.severe("file doesn't exist or is not a file");
- e.printStackTrace();
- } catch (IOException e) {
- logger.severe("The operation file is an IO exception.");
- e.printStackTrace();
- }
- return null;
- }
-
/**
* 文件md5
*
@@ -195,66 +150,40 @@ public class FileUtil {
* @return
*/
public static String md5(File file) {
- FileInputStream in = null;
- try {
- in = new FileInputStream(file);
- MessageDigest digest = MessageDigest.getInstance("MD5");
- byte[] buffer = new byte[1024 * 1024 * 10];
-
- int len = 0;
- while ((len = in.read(buffer)) > 0) {
- digest.update(buffer, 0, len);
- }
- String md5 = new BigInteger(1, digest.digest()).toString(16);
- int length = 32 - md5.length();
- if (length > 0) {
- for (int i = 0; i < length; i++) {
- md5 = "0" + md5;
- }
- }
- return md5;
- } catch (IOException e) {
- logger.severe("The operation file is an IO exception.");
- } catch (NoSuchAlgorithmException e) {
- logger.severe("system algorithm error.");
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException e) {
- logger.severe("close FileInputStream IO exception.");
- }
- }
- return null;
+ return getDigest(file, "MD5");
}
/**
- * 对一个文件获取md5值
- *
- * @return md5串
- * @throws NoSuchAlgorithmException
+ * 获取文件的散列值
+ * @param file
+ * @param digestCode
+ * @return
*/
- public static String md5ByBigFile(File file) {
-
- MessageDigest messagedigest = null;
- try {
- messagedigest = MessageDigest.getInstance("MD5");
- FileInputStream in = new FileInputStream(file);
- FileChannel ch = in.getChannel();
- MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
- file.length());
- messagedigest.update(byteBuffer);
- return StrUtil.toHex(messagedigest.digest());
+ private static String getDigest(File file, String digestCode) {
+ try (FileInputStream in = new FileInputStream(file)) {
+ MessageDigest digest = MessageDigest.getInstance(digestCode);
+ FileChannel channel = in.getChannel();
+ ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); // 1MB 缓冲区
+ // 读取文件内容并更新 MessageDigest
+ while (channel.read(buffer) != -1) {
+ buffer.flip(); // 将 Buffer 从写模式切换到读模式
+ digest.update(buffer); // 更新 MessageDigest
+ buffer.clear(); // 清空 Buffer
+ }
+ // 计算最终的 SHA-1 散列值
+ byte[] sha1Bytes = digest.digest();
+ // 将字节数组转换为十六进制字符串
+ StringBuilder sha1Builder = new StringBuilder();
+ for (byte b : sha1Bytes) {
+ sha1Builder.append(String.format("%02x", b));
+ }
+ return sha1Builder.toString();
} catch (NoSuchAlgorithmException e) {
- logger.severe("system algorithm error.");
- e.printStackTrace();
+ logger.log(Level.SEVERE, "system algorithm error.", e);
} catch (FileNotFoundException e) {
- logger.severe("file doesn't exist or is not a file");
- e.printStackTrace();
+ logger.log(Level.SEVERE, "file doesn't exist or is not a file", e);
} catch (IOException e) {
- logger.severe("The operation file is an IO exception.");
- e.printStackTrace();
+ logger.log(Level.SEVERE, "The operation file is an IO exception.", e);
}
return null;
}
@@ -262,37 +191,24 @@ public class FileUtil {
/**
* 获取文件CRC32码
*
- * @return String
+ * @return 获取失败返回-1
*/
- public static String crc32(File file) {
+ public static long crc32(File file) {
CRC32 crc32 = new CRC32();
// MessageDigest.get
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(file);
- byte[] buffer = new byte[8192];
+ try (FileInputStream fileInputStream = new FileInputStream(file);) {
+ byte[] buffer = new byte[1024 * 1024];
int length;
while ((length = fileInputStream.read(buffer)) != -1) {
crc32.update(buffer, 0, length);
}
- return crc32.getValue() + "";
+ return crc32.getValue();
} catch (FileNotFoundException e) {
- logger.severe("file doesn't exist or is not a file");
- e.printStackTrace();
- return null;
+ logger.log(Level.SEVERE, "file doesn't exist or is not a file", e);
+ return -1;
} catch (IOException e) {
- logger.severe("The operation file is an IO exception.");
- e.printStackTrace();
- return null;
- } finally {
- try {
- if (fileInputStream != null) {
- fileInputStream.close();
- }
- } catch (IOException e) {
- logger.severe("close FileInputStream IO exception.");
- e.printStackTrace();
- }
+ logger.log(Level.SEVERE, "The operation file is an IO exception.", e);
+ return -1;
}
}
@@ -303,44 +219,27 @@ public class FileUtil {
* @return
*/
public static String base64ToStr(File file) {
- return new String(base64(file));
- }
-
- /**
- * 获取文件base64
- *
- * @param file
- * @return
- */
- public static byte[] base64(File file) {
- FileInputStream fileInputStream = null;
- byte[] data = null;
- // 读取图片字节数组
try {
- fileInputStream = new FileInputStream(file);
- data = new byte[fileInputStream.available()];
- fileInputStream.read(data);
- fileInputStream.close();
+ byte[] bytes = Files.readAllBytes(Paths.get(file.getPath()));
+ return Base64.getEncoder().encodeToString(bytes);
} catch (IOException e) {
logger.severe("The operation file is an IO exception.");
- e.printStackTrace();
}
- // 对字节数组Base64编码
- return Base64.getEncoder().encode(data);
+ return null;
}
/**
* base64转文件
*
*
- * 文件转base64请使用 {@link FileUtil#base64(File)}
+ * 文件转base64请使用 {@link FileUtil#base64ToStr(File)}
*
*
* @param decode {@link FileUtil#base64ToStr(File)} 的结果
* @param fileName 文件名称(包含路径)
* @return 返回保存地址
*/
- public static String base64ToFile(String decode, String fileName) {
+ public static String base64ToFile(String decode, String fileName) throws IOException {
return base64ToFile(Base64.getDecoder().decode(decode.getBytes()), fileName);
}
@@ -348,29 +247,16 @@ public class FileUtil {
* base64转文件
*
*
- * 文件转base64请使用 {@link FileUtil#base64(File)}
+ * 文件转base64请使用 {@link FileUtil#base64ToStr(File)}}
*
*
* @param decode baseByte
* @param fileName 文件名称(包含路径)
* @return 返回保存地址
*/
- public static String base64ToFile(byte[] decode, String fileName) {
-
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(fileName);
+ public static String base64ToFile(byte[] decode, String fileName) throws IOException {
+ try (FileOutputStream out = new FileOutputStream(fileName)) {
out.write(decode);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- } finally {
- try {
- if (out != null) {
- out.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
}
return fileName;
}
@@ -378,50 +264,18 @@ public class FileUtil {
/**
* 获取文件大小 :直接返回大小
*
- * @param f
+ * @param path 文件地址
* @return f.length()
*/
- public static long size(File f) {
- if (f.exists() && f.isFile()) {
- return f.length();
+ public static long size(Path path) throws IOException {
+ if (Files.exists(path) && Files.isRegularFile(path)) {
+ return Files.size(path);
} else {
logger.info("file doesn't exist or is not a file");
}
return 0;
}
- /**
- * 获取文件大小 : 用流的方式获取
- *
- * @param f
- * @return
- */
- public static long size4Stream(File f) {
- FileChannel fc = null;
- try {
- if (f.exists() && f.isFile()) {
- FileInputStream fis = new FileInputStream(f);
- fc = fis.getChannel();
- return fc.size();
- } else {
- logger.info("file doesn't exist or is not a file");
- }
- } catch (FileNotFoundException e) {
- logger.severe("file doesn't exist or is not a file");
- } catch (IOException e) {
- logger.severe("The operation file is an IO exception.");
- } finally {
- if (null != fc) {
- try {
- fc.close();
- } catch (IOException e) {
- logger.severe("close FileInputStream IO exception.");
- }
- }
- }
- return 0;
- }
-
/**
* 字符串(csv格式)转 对象
*
@@ -448,14 +302,15 @@ public class FileUtil {
*
* @param csvFilePath 文件地址
* @param cls 读取转化的对象
- * @param hasHeader 是否存在header
+ * @param header 解析列对应的java字段;用delimiter分割
+ * @param hasHeader csv文件中第一行是否是header
* @param delimiter 分隔符.默认【,】
* @param
* @return
*/
- public static List readCsv(final String csvFilePath, Class cls, boolean hasHeader, char delimiter) {
+ public static List readCsv(final String csvFilePath, Class cls, boolean hasHeader, String header, char delimiter) {
if (!isFileExist(csvFilePath)) {
- throw new RuntimeException(String.format("解析用的csv:\u0020[%s] 文件不存在。", csvFilePath));
+ throw new RuntimeException(String.format("解析用的csv: [%s] 文件不存在。", csvFilePath));
}
if (StrUtil.isEmpty(delimiter)) {
delimiter = ',';
@@ -463,7 +318,12 @@ public class FileUtil {
try {
File csvFile = new File(csvFilePath);
CsvMapper csvMapper = new CsvMapper();
- CsvSchema csvSchema = csvMapper.typedSchemaFor(cls).withStrictHeaders(hasHeader).withColumnSeparator(delimiter).withComments();
+ CsvSchema.Builder builder = CsvSchema.builder();
+ if (StrUtil.isNotEmpty(header)) {
+ builder.addColumns(Arrays.asList(header.split(String.valueOf(delimiter))), CsvSchema.ColumnType.STRING);
+ }
+ CsvSchema csvSchema = builder.build().withColumnSeparator(delimiter).withSkipFirstDataRow(hasHeader).withStrictHeaders(hasHeader).withComments();
+
MappingIterator recordIterator = csvMapper.readerWithTypedSchemaFor(cls).with(csvSchema).readValues(csvFile);
return recordIterator.readAll();
} catch (IOException e) {
@@ -471,70 +331,74 @@ public class FileUtil {
}
}
- /**
- * 判断文件是否存在
- *
- * @param filePath
- * @return
- */
- public static boolean isFileExist(String filePath) {
- if (StrUtil.isEmpty(filePath)) {
- return false;
- }
-
- File file = new File(filePath);
- return file.exists() && !file.isDirectory();
- }
-
/**
* 分段读取大文件
*
- * @param path 文件路径
+ * @param csvFilePath 文件路径
* @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数
* @param 读取结果类型bean
* @return
*/
- public ReadFileBean readBigFile(String path, ReadFileBean readFileBean, Class readCls) {
- File file = new File(path);
- judeFileExists(file);
- try {
- RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
+ public static ReadFileBean readBigFile(String csvFilePath, ReadFileBean readFileBean, Class readCls) throws IOException {
+ if (!isFileExist(csvFilePath)) {
+ throw new FileNotFoundException(String.format("解析用的csv: [%s] 文件不存在。", csvFilePath));
+ }
+ if (!csvFilePath.endsWith(TYPE_CSV)) {
+ throw new IOException(String.format("解析用的csv: [%s] 文件不是CSV文件格式。", csvFilePath));
+ }
+ List datas = new ArrayList<>();
+ try (RandomAccessFile randomAccessFile = new RandomAccessFile(new File(csvFilePath), "r")) {
+ if (readFileBean.getPointer() < 0) {
+ readFileBean.setPointer(0);
+ }
randomAccessFile.seek(readFileBean.getPointer());
readFileBean.setFileLength(randomAccessFile.length());
- List datas = new ArrayList<>();
- for (int i = 0; i < readFileBean.getReadRowNum(); i++) {
- String s = randomAccessFile.readLine();
- datas.add(charsetDecode(s, StandardCharsets.UTF_8));
+ int row = 0;
+ String line;
+ while ((line = randomAccessFile.readLine()) != null && row <= readFileBean.getReadRowNum()) {
+ row++;
readFileBean.setPointer(randomAccessFile.getFilePointer());
+ datas.add(readFileBean.lineScavenge(charsetDecode(line, readFileBean.getReadCharset())));
}
- randomAccessFile.close();
- if (path.contains(TYPE_CSV)) {
- //csv文件处理
- datas.add(0, getCsvHeader(readCls));
- List dataList = readCsv(String.join("\n", datas), readCls, ',');
- readFileBean.setDatas(dataList);
- }
- } catch (FileNotFoundException e) {
- logger.severe("file exists." + e.getMessage());
- } catch (IOException e) {
- logger.severe("read file error." + e.getMessage());
}
+ if (StrUtil.isEmpty(datas)) {
+ //无数据
+ return readFileBean.setDatas(new ArrayList<>());
+ }
+
+ //csv文件处理
+ com.yexuejc.base.pojo.CsvToBean csvToBean = getCsvToBean(readCls);
+ readFileBean.setHeader(csvToBean.getHeader());
+ if (csvToBean.hasHeader()) {
+ //文件存在header,设置header优先,没设置使用文件的
+ if (StrUtil.isNotEmpty(csvToBean.getHeader())) {
+ //替换header
+ datas.remove(0);
+ datas.add(0, csvToBean.getHeader());
+ } else {
+ readFileBean.setHeader(datas.get(0));
+ }
+ } else {
+ //文件不存在header,使用设置的
+ datas.add(0, csvToBean.getHeader());
+ }
+
+ List dataList = readCsv(String.join("\n", datas), readCls, csvToBean.getDelimiter());
+ readFileBean.setDatas(dataList);
return readFileBean;
}
/**
- * 获取csv的header,使用注解{@link CsvHeader}
+ * 获取csv的header,使用注解{@link CsvToBean}
*
* @param cls
* @param
* @return
*/
- public static String getCsvHeader(Class cls) {
- CsvHeader annotation = cls.getAnnotation(CsvHeader.class);
- Assert.notNull(annotation, cls.toString() + "类上需要添加注解@CsvHeader,并指定header。");
- String header = annotation.header();
- Assert.notNull(header, cls.toString() + "类上需要添加注解@CsvHeader,并指定header。");
- return header;
+ public static com.yexuejc.base.pojo.CsvToBean getCsvToBean(Class cls) {
+ CsvToBean annotation = cls.getAnnotation(CsvToBean.class);
+ Assert.notNull(annotation, cls + "类上需要添加注解@CsvToBean,并指定header。");
+ return new com.yexuejc.base.pojo.CsvToBean(annotation.header(), annotation.delimiter(), annotation.hasHeader());
}
/**
@@ -552,225 +416,4 @@ public class FileUtil {
}
return new String(result, charset);
}
-
-
- /**
- * 提供读取IO流方法合集
- * 读取速度快慢顺序:
- * 1. {@link #read4Buffer(InputStream, Charset)}
- * 2. {@link #read4IOUtilsCopy(InputStream, Charset)}
- * 3. {@link #read4ByteStreams(InputStream, Charset)}
- * 4. {@link #read4Byte(InputStream, Charset)}
- * 5. {@link #read4StringBuilder(InputStream, Charset)}
- * 6. {@link #read4BufferedReaderParallel(InputStream, Charset, String)}
- * 7. {@link #read4BufferedReader(InputStream, Charset, String)}
- * 8. {@link #read4ScannerA(InputStream)}
- * 9. {@link #read4BufferIO(InputStream, Charset)}
- * 10. {@link #read4IOUtils(InputStream, Charset)}
- * 11. {@link #read4ScannerZ(InputStream)}
- * 12. {@link #read4CharStreams(InputStream, Charset)}
- */
- public static class FileInput {
- /**
- * 读取IO流内容:byte方式
- *
- * @param inputStream
- * @param charset 编码:默认 {@link Charset#defaultCharset()}
- * @return
- * @throws IOException
- */
- public static String read4Byte(InputStream inputStream, Charset charset) throws IOException {
- byte[] bytes = new byte[inputStream.available()];
- inputStream.read(bytes);
- return new String(bytes, charset == null ? Charset.defaultCharset() : charset);
- }
-
- /**
- * 读取IO流内容:BufferedReader方式
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @param lineSeparator 换行方式:默认跟随系统 {@link System#lineSeparator()}
- * @return
- */
- public static String read4BufferedReader(InputStream inputStream, Charset charset, String lineSeparator) {
- return new BufferedReader(
- new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset)
- ).lines().collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator));
- }
-
- /**
- * 读取IO流内容:BufferedReader 并行方式
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @param lineSeparator 换行方式:默认跟随系统 {@link System#lineSeparator()}
- * @return
- */
- public static String read4BufferedReaderParallel(InputStream inputStream, Charset charset, String lineSeparator) {
- return new BufferedReader(
- new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset)
- ).lines().parallel()
- .collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator));
- }
-
-
- /**
- * 读取IO流内容:Scanner A方式
- *
- * @param inputStream
- * @return
- */
- public static String read4ScannerA(InputStream inputStream) {
- Scanner s = new Scanner(inputStream).useDelimiter("\\A");
- String str = s.hasNext() ? s.next() : "";
- return str;
- }
-
- /**
- * 读取IO流内容:Scanner Z方式
- *
- * @param inputStream
- * @return
- */
- public static String read4ScannerZ(InputStream inputStream) {
- return new Scanner(inputStream).useDelimiter("\\Z").next();
- }
-
-
- /**
- * 读取IO流内容:StringBuilder方式
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- */
- public static String read4StringBuilder(InputStream inputStream, Charset charset) throws IOException {
- StringBuilder sb = new StringBuilder();
- String line;
- BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset));
- while ((line = br.readLine()) != null) {
- sb.append(line);
- }
- return sb.toString();
- }
-
- /**
- * 读取IO流内容:ByteArrayOutputStream方式
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- */
- public static String read4Buffer(InputStream inputStream, Charset charset) throws IOException {
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int length;
- while ((length = inputStream.read(buffer)) != -1) {
- result.write(buffer, 0, length);
- }
- return result.toString(charset == null ? Charset.defaultCharset().name() : charset.name());
- }
-
- /**
- * 读取IO流内容:BufferedInputStream+ByteArrayOutputStream方式
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- */
- public static String read4BufferIO(InputStream inputStream, Charset charset) throws IOException {
- BufferedInputStream bis = new BufferedInputStream(inputStream);
- ByteArrayOutputStream buf = new ByteArrayOutputStream();
- int result = bis.read();
- while (result != -1) {
- buf.write((byte) result);
- result = bis.read();
- }
- return buf.toString(charset == null ? Charset.defaultCharset().name() : charset.name());
- }
-
- /**
- * 读取IO流内容: 依赖于commons-io:commons-io {@link IOUtils#copy(Reader, OutputStream, Charset)}
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- * @throws IOException
- */
- public static String read4IOUtilsCopy(InputStream inputStream, Charset charset) throws IOException {
- StringWriter writer = new StringWriter();
- IOUtils.copy(inputStream, writer, charset == null ? Charset.defaultCharset() : charset);
- return writer.toString();
- }
-
- /**
- * 读取IO流内容: 依赖于commons-io:commons-io {@link IOUtils#toString(InputStream, Charset)}
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- * @throws IOException
- */
- public static String read4IOUtils(InputStream inputStream, Charset charset) throws IOException {
- return IOUtils.toString(inputStream, charset == null ? Charset.defaultCharset() : charset);
- }
-
- /**
- * 读取IO流内容: 依赖于com.google.guava:guava {@link CharStreams#toString(Readable)}
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- * @throws IOException
- */
- public static String read4CharStreams(InputStream inputStream, Charset charset) throws IOException {
- return CharStreams.toString(new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset));
- }
-
- /**
- * 读取IO流内容: 依赖于com.google.guava:guava {@link ByteStreams#toByteArray(InputStream)}
- *
- * @param inputStream
- * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
- * @return
- * @throws IOException
- */
- public static String read4ByteStreams(InputStream inputStream, Charset charset) throws IOException {
- return new String(ByteStreams.toByteArray(inputStream), charset == null ? Charset.defaultCharset() : charset);
- }
- }
-
- /*public static void main(String[] args) {
- long size = FileUtil.size(new File("E:\\OS\\deepin-15.6-amd64\\DeepinCloudPrintServerInstaller_1.0.0.1.exe"));
- System.out.println(size);
- System.out.println(1024 * 1024 * 5);
- if (size > 1024 * 1024 * 5) {
- System.out.println("文件最大5M");
- return;
- }
-
- long s1 = fileSize(new File("E:\\OS\\cn_windows_10_consumer_editions_version_1803_updated_march_2018_x64_dvd_12063766.iso"));
- System.out.println(s1);
- long s2 = fileSize4Stream(new File("E:\\OS\\cn_windows_10_consumer_editions_version_1803_updated_march_2018_x64_dvd_12063766.iso"));
- System.out.println(s2);
-
- String s1 = base64(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
- System.out.println(s1);
-
- String s = sha1(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
- String s2 = sha1ByBigFile(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
- System.out.println(s);
- System.out.println(s2);
-
-
- String md5 = md5(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
- String md52 = md5ByBigFile(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
- System.out.println(md5);
- System.out.println(md52);
-
-
- String crc32 = crc32(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
- System.out.println(crc32);
- }*/
}
diff --git a/src/main/java/com/yexuejc/base/util/JsonUtil.java b/src/main/java/com/yexuejc/base/util/JsonUtil.java
index faa5fe8..bea3786 100644
--- a/src/main/java/com/yexuejc/base/util/JsonUtil.java
+++ b/src/main/java/com/yexuejc/base/util/JsonUtil.java
@@ -1,19 +1,37 @@
package com.yexuejc.base.util;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.logging.Logger;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.type.MapType;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.logging.Logger;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.yexuejc.base.converter.LocalDateDeserializer;
+import com.yexuejc.base.converter.LocalDateSerializer;
+import com.yexuejc.base.converter.LocalDateTimeDeserializer;
+import com.yexuejc.base.converter.LocalDateTimeSerializer;
+import com.yexuejc.base.converter.TimestampDeserializer;
+import com.yexuejc.base.converter.TimestampSerializer;
/**
* json工具类,基于jackson
@@ -24,7 +42,7 @@ import java.util.logging.Logger;
* @date 2018/9/3 15:28
*/
public class JsonUtil {
- private static Logger log = Logger.getLogger(JsonUtil.class.getName());
+ private static final Logger log = Logger.getLogger(JsonUtil.class.getName());
private JsonUtil() {
}
@@ -32,32 +50,103 @@ public class JsonUtil {
/**
* 作为单例全局使用
*/
- private static ObjectMapper objectMapper = new ObjectMapper();
+ private static final JsonMapper jsonMapper = new JsonMapper();
static {
- JsonUtil.initDefaultObjectMapper(JsonUtil.objectMapper);
+ JsonUtil.initDefaultObjectMapper(JsonUtil.jsonMapper);
+ }
+
+ /**
+ * 对时间的支持
+ *
+ * @param jsonMapper
+ */
+ private static void setJavaTimeModule(ObjectMapper jsonMapper) {
+ //设置一下时区,可以和程序同步避免时区问题
+ jsonMapper.setTimeZone(TimeZone.getDefault());
+ jsonMapper.setDateFormat(DateUtil.DATE_TIME_FORMAT);
+
+ JavaTimeModule javaTime = new JavaTimeModule();
+ //java time 特殊处理
+ javaTime.addSerializer(LocalDate.class, new LocalDateSerializer());
+ javaTime.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
+ javaTime.addSerializer(Timestamp.class, new TimestampSerializer());
+
+ javaTime.addDeserializer(LocalDate.class, new LocalDateDeserializer());
+ javaTime.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
+ javaTime.addDeserializer(Timestamp.class, new TimestampDeserializer());
+ jsonMapper.registerModule(javaTime);
}
/**
* 初始化ObjectMapper为默认属性
+ *
+ * 1.序列化值为空时,NON_NULL:舍去字段
+ * 2.JsonParser.Feature.ALLOW_SINGLE_QUOTES:解析JSON时允许使用单引号(')作为字符串的引号(true)
+ * 例子:{'localDateTime':'2023-05-29T15:32:03.9770447'}
+ * 3.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES:解析JSON时允许不使用引号作为字符串的引号(true)
+ * 例子:{age:12};适用于基本数据类型
+ * 4.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES:json对应java Bean,数据字段对不齐的情况下不报错(false)
+ * 5.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS(false):用于指定是否将日期类型序列化为时间戳格式。如果启用该特性,则日期类型将被序列化为Unix时间戳(即从1970年1月1日00:00:00 GMT开始的毫秒数)。如果禁用该特性,则日期类型将以其原始格式进行序列化。
+ * 例子(false):"timestamp": "2020-07-08T02:02:55.000+00:00"
+ * 例子(true):"timestamp": 1594236175000
+ *
*
- * @param objectMapper
+ * @param jsonMapper
+ * @return
*/
- private static void initDefaultObjectMapper(ObjectMapper objectMapper) {
- objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
- objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
- //设置一下时区,可以和程序同步避免时区问题
- objectMapper.setTimeZone(TimeZone.getDefault());
- objectMapper.setDateFormat(DateUtil.DATE_TIME_FORMAT);
+ private static ObjectMapper initDefaultObjectMapper(ObjectMapper jsonMapper) {
+ JsonUtil.setJavaTimeModule(jsonMapper);
+ //值为空时,NON_NULL:舍去字段;ALWAYS:保留字段
+ jsonMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ jsonMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
+ jsonMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+ jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ return jsonMapper;
+ }
+
+ /**
+ * 初始化ObjectMapper的默认属性
+ *
+ * 1.序列化值为空时,ALWAYS:保留字段,值为“”
+ * 2.JsonParser.Feature.ALLOW_SINGLE_QUOTES:解析JSON时允许使用单引号(')作为字符串的引号(true)
+ * 例子:{'localDateTime':'2023-05-29T15:32:03.9770447'}
+ * 3.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES:解析JSON时允许不使用引号作为字符串的引号(true)
+ * 例子:{age:12};适用于基本数据类型
+ * 4.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES:json对应java Bean,数据字段对不齐的情况下不报错(false)
+ * 5.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS(false):用于指定是否将日期类型序列化为时间戳格式。如果启用该特性,则日期类型将被序列化为Unix时间戳(即从1970年1月1日00:00:00 GMT开始的毫秒数)。如果禁用该特性,则日期类型将以其原始格式进行序列化。
+ * 例子(false):"timestamp": "2020-07-08T02:02:55.000+00:00"
+ * 例子(true):"timestamp": 1594236175000
+ * 6.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT:反序列化值为空时,映射到java Bean 非字符串类型,值为:null
+ *
+ *
+ * @return
+ */
+ public static ObjectMapper acceptEmptyStringAsNullObject(JsonMapper jsonMapper) {
+ setJavaTimeModule(jsonMapper);
+ //值为空时,ALWAYS:保留字段,默认字符串值为“”,对象值为null
+ jsonMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
+ jsonMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
+ jsonMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+ jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ jsonMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
+
+ //值为空时,序列化所有值为“”
+ jsonMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer