generated from mingliqiye/lib-tem
no message
All checks were successful
Gitea Actions Build / Build (push) Successful in 53s
All checks were successful
Gitea Actions Build / Build (push) Successful in 53s
This commit is contained in:
parent
0376ef3a9d
commit
09792e2c3b
@ -16,7 +16,7 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils
|
||||
* CurrentFile build.gradle.kts
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* LastUpdate 2025-09-10 11:08:55
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
@ -25,6 +25,7 @@ import java.time.format.DateTimeFormatter
|
||||
|
||||
plugins {
|
||||
idea
|
||||
java
|
||||
id("java-library")
|
||||
id("maven-publish")
|
||||
}
|
||||
@ -61,11 +62,6 @@ dependencies {
|
||||
}
|
||||
|
||||
|
||||
sourceSets.main.configure {
|
||||
java.setSrcDirs(files("src"))
|
||||
resources.setSrcDirs(files("resources"))
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
@ -22,4 +22,4 @@
|
||||
JDKVERSIONS=1.8
|
||||
GROUPSID=com.mingliqiye.utils
|
||||
ARTIFACTID=mingli-utils
|
||||
VERSIONS=3.0.1
|
||||
VERSIONS=3.0.3
|
||||
|
||||
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile JsonApi.java
|
||||
* LastUpdate 2025-09-09 09:22:02
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.json;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JSON处理接口,提供JSON字符串与Java对象之间的相互转换功能
|
||||
*/
|
||||
public interface JsonApi {
|
||||
/**
|
||||
* 将JSON字符串解析为指定类型的对象
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param clazz 目标对象的Class类型
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
<T> T parse(String json, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定泛型类型对象
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param type 目标对象的Type类型(支持泛型)
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
<T> T parse(String json, JsonTypeReference<T> type);
|
||||
|
||||
/**
|
||||
* 将对象格式化为JSON字符串
|
||||
*
|
||||
* @param object 待格式化的对象
|
||||
* @return 格式化后的JSON字符串
|
||||
*/
|
||||
String format(Object object);
|
||||
|
||||
/**
|
||||
* 将字节数组形式的JSON解析为指定类型的对象
|
||||
*
|
||||
* @param json 待解析的JSON字节数组
|
||||
* @param clazz 目标对象的Class类型
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
default <T> T parse(byte[] json, Class<T> clazz) {
|
||||
return parse(new String(json), clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组形式的JSON解析为指定泛型类型对象
|
||||
*
|
||||
* @param json 待解析的JSON字节数组
|
||||
* @param type 目标对象的Type类型(支持泛型)
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
default <T> T parse(byte[] json, JsonTypeReference<T> type) {
|
||||
return parse(new String(json), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定类型的对象,解析失败时返回默认值
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param clazz 目标对象的Class类型
|
||||
* @param defaultValue 解析失败时返回的默认值
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例或默认值
|
||||
*/
|
||||
default <T> T parse(String json, Class<T> clazz, T defaultValue) {
|
||||
try {
|
||||
return parse(json, clazz);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定泛型类型对象,解析失败时返回默认值
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param type 目标对象的Type类型(支持泛型)
|
||||
* @param defaultValue 解析失败时返回的默认值
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例或默认值
|
||||
*/
|
||||
default <T> T parse(
|
||||
String json,
|
||||
JsonTypeReference<T> type,
|
||||
T defaultValue
|
||||
) {
|
||||
try {
|
||||
return parse(json, type);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象格式化为美化格式的JSON字符串(带缩进和换行)
|
||||
*
|
||||
* @param object 待格式化的对象
|
||||
* @return 格式化后的美化JSON字符串
|
||||
*/
|
||||
String formatPretty(Object object);
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定元素类型的List集合
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param elementType List中元素的类型
|
||||
* @param <T> 泛型参数,表示List中元素的类型
|
||||
* @return 解析后的List集合
|
||||
*/
|
||||
default <T> List<T> parseList(String json, Class<T> elementType) {
|
||||
return parse(json, JsonTypeUtils.listType(elementType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定键值类型的Map集合
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param keyType Map中键的类型
|
||||
* @param valueType Map中值的类型
|
||||
* @param <K> 泛型参数,表示Map中键的类型
|
||||
* @param <V> 泛型参数,表示Map中值的类型
|
||||
* @return 解析后的Map集合
|
||||
*/
|
||||
default <K, V> Map<K, V> parseMap(
|
||||
String json,
|
||||
Class<K> keyType,
|
||||
Class<V> valueType
|
||||
) {
|
||||
JsonTypeReference<Map<K, V>> mapType = new JsonTypeReference<
|
||||
Map<K, V>
|
||||
>() {};
|
||||
return parse(json, mapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字符串是否为有效的JSON格式
|
||||
*
|
||||
* @param json 待验证的字符串
|
||||
* @return 如果是有效的JSON格式返回true,否则返回false
|
||||
*/
|
||||
boolean isValidJson(String json);
|
||||
|
||||
/**
|
||||
* 将对象转换为JSON字节数组
|
||||
*
|
||||
* @param object 待转换的对象
|
||||
* @return 转换后的JSON字节数组
|
||||
*/
|
||||
default byte[] toBytes(Object object) {
|
||||
return format(object).getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转换为美化格式的JSON字节数组
|
||||
*
|
||||
* @param object 待转换的对象
|
||||
* @return 转换后的美化格式JSON字节数组
|
||||
*/
|
||||
default byte[] toBytesPretty(Object object) {
|
||||
return formatPretty(object).getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并多个JSON字符串为一个JSON对象
|
||||
*
|
||||
* @param jsons 待合并的JSON字符串数组
|
||||
* @return 合并后的JSON字符串
|
||||
*/
|
||||
String merge(String... jsons);
|
||||
|
||||
/**
|
||||
* 获取JSON字符串中指定路径节点的值
|
||||
*
|
||||
* @param json JSON字符串
|
||||
* @param path 节点路径(如:"user.name")
|
||||
* @return 节点值的字符串表示
|
||||
*/
|
||||
String getNodeValue(String json, String path);
|
||||
|
||||
/**
|
||||
* 更新JSON字符串中指定路径节点的值
|
||||
*
|
||||
* @param json 原始JSON字符串
|
||||
* @param path 节点路径(如:"user.name")
|
||||
* @param newValue 新的节点值
|
||||
* @return 更新后的JSON字符串
|
||||
*/
|
||||
String updateNodeValue(String json, String path, Object newValue);
|
||||
|
||||
<T, D> D convert(T source, Class<D> destinationClass);
|
||||
<T, D> D convert(T source, JsonTypeReference<D> destinationType);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,12 +22,21 @@
|
||||
|
||||
package com.mingliqiye.utils;
|
||||
|
||||
import com.mingliqiye.utils.collection.Lists;
|
||||
import com.mingliqiye.utils.collection.Maps;
|
||||
import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration;
|
||||
import com.mingliqiye.utils.stream.SuperStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
AutoConfiguration.printBanner();
|
||||
|
||||
Map<String, String> map = Maps.of("1", "2", "3", "4");
|
||||
|
||||
SuperStream.of(map).entryToMap();
|
||||
}
|
||||
}
|
||||
@ -282,9 +282,7 @@ public class Lists {
|
||||
return null;
|
||||
}
|
||||
T[] items = (T[]) new Object[ts.size()];
|
||||
ForEach.forEach(ts, (t, i) -> {
|
||||
items[i] = t;
|
||||
});
|
||||
ForEach.forEach(ts, (t, i) -> items[i] = t);
|
||||
return items;
|
||||
}
|
||||
|
||||
@ -15974,4 +15974,12 @@ public class Maps {
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static <K, V> Map<K, V> ofEntries(List<Map.Entry<K, V>> entries) {
|
||||
var map = new HashMap<K, V>(entries.size() + 2);
|
||||
for (Map.Entry<K, V> entry : entries) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,9 @@ public class FileUtil {
|
||||
Charset charset
|
||||
) throws IOException {
|
||||
Path path = Paths.get(filePath);
|
||||
Files.createDirectories(path.getParent());
|
||||
if (path.getParent() != null) {
|
||||
Files.createDirectories(path.getParent());
|
||||
}
|
||||
Files.write(path, content.getBytes(charset));
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
package com.mingliqiye.utils.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@ -51,7 +52,7 @@ public class JacksonJsonApi implements JsonApi {
|
||||
* @param objectMapper 自定义的ObjectMapper实例
|
||||
*/
|
||||
public JacksonJsonApi(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.objectMapper = objectMapper.copy();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,6 +113,18 @@ public class JacksonJsonApi implements JsonApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatUnicode(Object object) {
|
||||
try {
|
||||
return objectMapper
|
||||
.writer()
|
||||
.with(JsonGenerator.Feature.ESCAPE_NON_ASCII)
|
||||
.writeValueAsString(object);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new JsonException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象格式化为美化(带缩进)的JSON字符串
|
||||
*
|
||||
@ -133,6 +146,21 @@ public class JacksonJsonApi implements JsonApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatPrettyUnicode(Object object) {
|
||||
try {
|
||||
return objectMapper
|
||||
.writerWithDefaultPrettyPrinter()
|
||||
.with(JsonGenerator.Feature.ESCAPE_NON_ASCII)
|
||||
.writeValueAsString(object);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new JsonException(
|
||||
"Failed to format object to pretty JSON string",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定元素类型的List
|
||||
*
|
||||
@ -283,10 +311,10 @@ public class JacksonJsonApi implements JsonApi {
|
||||
/**
|
||||
* 在不同对象类型之间进行转换
|
||||
*
|
||||
* @param source 源对象
|
||||
* @param destinationClass 目标对象类型
|
||||
* @param <T> 源对象类型
|
||||
* @param <D> 目标对象类型
|
||||
* @param source 源对象
|
||||
* @param destinationClass 目标对象类型
|
||||
* @param <T> 源对象类型
|
||||
* @param <D> 目标对象类型
|
||||
* @return 转换后的对象
|
||||
*/
|
||||
@Override
|
||||
@ -297,10 +325,10 @@ public class JacksonJsonApi implements JsonApi {
|
||||
/**
|
||||
* 在不同泛型对象类型之间进行转换
|
||||
*
|
||||
* @param source 源对象
|
||||
* @param destinationType 目标对象的泛型类型引用
|
||||
* @param <T> 源对象类型
|
||||
* @param <D> 目标对象类型
|
||||
* @param source 源对象
|
||||
* @param destinationType 目标对象的泛型类型引用
|
||||
* @param <T> 源对象类型
|
||||
* @param <D> 目标对象类型
|
||||
* @return 转换后的对象
|
||||
*/
|
||||
@Override
|
||||
393
src/main/java/com/mingliqiye/utils/json/JsonApi.java
Normal file
393
src/main/java/com/mingliqiye/utils/json/JsonApi.java
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile JsonApi.java
|
||||
* LastUpdate 2025-09-09 09:22:02
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.json;
|
||||
|
||||
import com.mingliqiye.utils.collection.Maps;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JSON处理接口,提供JSON字符串与Java对象之间的相互转换功能
|
||||
*/
|
||||
public interface JsonApi {
|
||||
final Map<String, String> UNICODE_BIND = Maps.of("1", "");
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定类型的对象
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param clazz 目标对象的Class类型
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
<T> T parse(String json, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定泛型类型对象
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param type 目标对象的Type类型(支持泛型)
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
<T> T parse(String json, JsonTypeReference<T> type);
|
||||
|
||||
/**
|
||||
* 将对象格式化为JSON字符串
|
||||
*
|
||||
* @param object 待格式化的对象
|
||||
* @return 格式化后的JSON字符串
|
||||
*/
|
||||
String format(Object object);
|
||||
|
||||
String formatUnicode(Object object);
|
||||
|
||||
default <T> T parseFrom(String path, Class<T> clazz) throws IOException {
|
||||
return parseFrom(Paths.get(path), clazz);
|
||||
}
|
||||
|
||||
default <T> T parseFrom(Path path, Class<T> clazz) throws IOException {
|
||||
return parseFrom(path.toFile(), clazz);
|
||||
}
|
||||
|
||||
default <T> T parseFrom(File file, Class<T> clazz) throws IOException {
|
||||
try (InputStream inputStream = Files.newInputStream(file.toPath())) {
|
||||
return parseFrom(inputStream, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
default <T> T parseFrom(InputStream inputStream, Class<T> clazz)
|
||||
throws IOException {
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("inputStream cannot be null");
|
||||
}
|
||||
if (clazz == null) {
|
||||
throw new IllegalArgumentException("clazz cannot be null");
|
||||
}
|
||||
byte[] bytes = new byte[1024];
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
||||
int readlength;
|
||||
while ((readlength = inputStream.read(bytes)) != -1) {
|
||||
bos.write(bytes, 0, readlength);
|
||||
}
|
||||
return parse(bos.toByteArray(), clazz);
|
||||
}
|
||||
}
|
||||
|
||||
default <T> T parseFrom(String path, JsonTypeReference<T> type)
|
||||
throws IOException {
|
||||
return parseFrom(Paths.get(path), type);
|
||||
}
|
||||
|
||||
default <T> T parseFrom(Path path, JsonTypeReference<T> type)
|
||||
throws IOException {
|
||||
return parseFrom(path.toFile(), type);
|
||||
}
|
||||
|
||||
default <T> T parseFrom(File file, JsonTypeReference<T> type)
|
||||
throws IOException {
|
||||
try (InputStream inputStream = Files.newInputStream(file.toPath())) {
|
||||
return parseFrom(inputStream, type);
|
||||
}
|
||||
}
|
||||
|
||||
default <T> T parseFrom(InputStream inputStream, JsonTypeReference<T> type)
|
||||
throws IOException {
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("inputStream cannot be null");
|
||||
}
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type cannot be null");
|
||||
}
|
||||
byte[] bytes = new byte[1024];
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
||||
int readlength;
|
||||
while ((readlength = inputStream.read(bytes)) != -1) {
|
||||
bos.write(bytes, 0, readlength);
|
||||
}
|
||||
return parse(bos.toByteArray(), type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组形式的JSON解析为指定类型的对象
|
||||
*
|
||||
* @param json 待解析的JSON字节数组
|
||||
* @param clazz 目标对象的Class类型
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
default <T> T parse(byte[] json, Class<T> clazz) {
|
||||
return parse(new String(json), clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组形式的JSON解析为指定泛型类型对象
|
||||
*
|
||||
* @param json 待解析的JSON字节数组
|
||||
* @param type 目标对象的Type类型(支持泛型)
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例
|
||||
*/
|
||||
default <T> T parse(byte[] json, JsonTypeReference<T> type) {
|
||||
return parse(new String(json), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定类型的对象,解析失败时返回默认值
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param clazz 目标对象的Class类型
|
||||
* @param defaultValue 解析失败时返回的默认值
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例或默认值
|
||||
*/
|
||||
default <T> T parse(String json, Class<T> clazz, T defaultValue) {
|
||||
try {
|
||||
return parse(json, clazz);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定泛型类型对象,解析失败时返回默认值
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param type 目标对象的Type类型(支持泛型)
|
||||
* @param defaultValue 解析失败时返回的默认值
|
||||
* @param <T> 泛型参数,表示目标对象的类型
|
||||
* @return 解析后的对象实例或默认值
|
||||
*/
|
||||
default <T> T parse(
|
||||
String json,
|
||||
JsonTypeReference<T> type,
|
||||
T defaultValue
|
||||
) {
|
||||
try {
|
||||
return parse(json, type);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象格式化为美化格式的JSON字符串(带缩进和换行)
|
||||
*
|
||||
* @param object 待格式化的对象
|
||||
* @return 格式化后的美化JSON字符串
|
||||
*/
|
||||
String formatPretty(Object object);
|
||||
|
||||
default byte[] formatPrettyBytes(Object object) {
|
||||
return formatPretty(object).getBytes();
|
||||
}
|
||||
|
||||
String formatPrettyUnicode(Object object);
|
||||
|
||||
default byte[] formatPrettyUnicodeBytes(Object object) {
|
||||
return formatPrettyUnicode(object).getBytes();
|
||||
}
|
||||
|
||||
default void formatPretty(Object object, String file) throws IOException {
|
||||
formatPretty(object, Paths.get(file));
|
||||
}
|
||||
|
||||
default void formatPretty(Object object, Path file) throws IOException {
|
||||
formatPretty(object, file.toFile());
|
||||
}
|
||||
|
||||
default void formatPretty(Object object, File file) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
formatPretty(object, fos);
|
||||
}
|
||||
}
|
||||
|
||||
default void formatPretty(Object object, OutputStream stream)
|
||||
throws IOException {
|
||||
stream.write(formatPrettyBytes(object));
|
||||
}
|
||||
|
||||
default void formatPrettyUnicode(Object object, String file)
|
||||
throws IOException {
|
||||
formatPrettyUnicode(object, Paths.get(file));
|
||||
}
|
||||
|
||||
default void formatPrettyUnicode(Object object, Path file)
|
||||
throws IOException {
|
||||
formatPrettyUnicode(object, file.toFile());
|
||||
}
|
||||
|
||||
default void formatPrettyUnicode(Object object, File file)
|
||||
throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
formatPrettyUnicode(object, fos);
|
||||
}
|
||||
}
|
||||
|
||||
default void formatPrettyUnicode(Object object, OutputStream stream)
|
||||
throws IOException {
|
||||
stream.write(formatPrettyUnicodeBytes(object));
|
||||
}
|
||||
|
||||
default byte[] formatBytes(Object object) {
|
||||
return format(object).getBytes();
|
||||
}
|
||||
|
||||
default byte[] formatUnicodeBytes(Object object) {
|
||||
return formatUnicode(object).getBytes();
|
||||
}
|
||||
|
||||
default void format(Object object, String file) throws IOException {
|
||||
format(object, Paths.get(file));
|
||||
}
|
||||
|
||||
default void format(Object object, Path file) throws IOException {
|
||||
format(object, file.toFile());
|
||||
}
|
||||
|
||||
default void format(Object object, File file) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
format(object, fos);
|
||||
}
|
||||
}
|
||||
|
||||
default void format(Object object, OutputStream stream) throws IOException {
|
||||
stream.write(formatPrettyBytes(object));
|
||||
}
|
||||
|
||||
default void formatUnicode(Object object, String file) throws IOException {
|
||||
formatUnicode(object, Paths.get(file));
|
||||
}
|
||||
|
||||
default void formatUnicode(Object object, Path file) throws IOException {
|
||||
formatUnicode(object, file.toFile());
|
||||
}
|
||||
|
||||
default void formatUnicode(Object object, File file) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
formatUnicode(object, fos);
|
||||
}
|
||||
}
|
||||
|
||||
default void formatUnicode(Object object, OutputStream stream)
|
||||
throws IOException {
|
||||
stream.write(formatPrettyUnicodeBytes(object));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定元素类型的List集合
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param elementType List中元素的类型
|
||||
* @param <T> 泛型参数,表示List中元素的类型
|
||||
* @return 解析后的List集合
|
||||
*/
|
||||
default <T> List<T> parseList(String json, Class<T> elementType) {
|
||||
return parse(json, JsonTypeUtils.listType(elementType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON字符串解析为指定键值类型的Map集合
|
||||
*
|
||||
* @param json 待解析的JSON字符串
|
||||
* @param keyType Map中键的类型
|
||||
* @param valueType Map中值的类型
|
||||
* @param <K> 泛型参数,表示Map中键的类型
|
||||
* @param <V> 泛型参数,表示Map中值的类型
|
||||
* @return 解析后的Map集合
|
||||
*/
|
||||
default <K, V> Map<K, V> parseMap(
|
||||
String json,
|
||||
Class<K> keyType,
|
||||
Class<V> valueType
|
||||
) {
|
||||
JsonTypeReference<Map<K, V>> mapType = new JsonTypeReference<
|
||||
Map<K, V>
|
||||
>() {};
|
||||
return parse(json, mapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字符串是否为有效的JSON格式
|
||||
*
|
||||
* @param json 待验证的字符串
|
||||
* @return 如果是有效的JSON格式返回true,否则返回false
|
||||
*/
|
||||
boolean isValidJson(String json);
|
||||
|
||||
/**
|
||||
* 将对象转换为JSON字节数组
|
||||
*
|
||||
* @param object 待转换的对象
|
||||
* @return 转换后的JSON字节数组
|
||||
*/
|
||||
default byte[] toBytes(Object object) {
|
||||
return format(object).getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转换为美化格式的JSON字节数组
|
||||
*
|
||||
* @param object 待转换的对象
|
||||
* @return 转换后的美化格式JSON字节数组
|
||||
*/
|
||||
default byte[] toBytesPretty(Object object) {
|
||||
return formatPretty(object).getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并多个JSON字符串为一个JSON对象
|
||||
*
|
||||
* @param jsons 待合并的JSON字符串数组
|
||||
* @return 合并后的JSON字符串
|
||||
*/
|
||||
String merge(String... jsons);
|
||||
|
||||
/**
|
||||
* 获取JSON字符串中指定路径节点的值
|
||||
*
|
||||
* @param json JSON字符串
|
||||
* @param path 节点路径(如:"user.name")
|
||||
* @return 节点值的字符串表示
|
||||
*/
|
||||
String getNodeValue(String json, String path);
|
||||
|
||||
/**
|
||||
* 更新JSON字符串中指定路径节点的值
|
||||
*
|
||||
* @param json 原始JSON字符串
|
||||
* @param path 节点路径(如:"user.name")
|
||||
* @param newValue 新的节点值
|
||||
* @return 更新后的JSON字符串
|
||||
*/
|
||||
String updateNodeValue(String json, String path, Object newValue);
|
||||
|
||||
<T, D> D convert(T source, Class<D> destinationClass);
|
||||
|
||||
<T, D> D convert(T source, JsonTypeReference<D> destinationType);
|
||||
}
|
||||
@ -31,4 +31,8 @@ public class JsonException extends RuntimeException {
|
||||
public JsonException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public JsonException(Throwable cause) {
|
||||
this(cause.getMessage(), cause);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.mingliqiye.utils.minecraft.pe.json;
|
||||
|
||||
import com.mingliqiye.utils.collection.ForEach;
|
||||
import com.mingliqiye.utils.file.FileUtil;
|
||||
import com.mingliqiye.utils.json.JsonApi;
|
||||
import com.mingliqiye.utils.json.JsonTypeReference;
|
||||
import com.mingliqiye.utils.string.StringUtil;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.val;
|
||||
|
||||
public class Pseudocryptography {
|
||||
|
||||
private final JsonApi jsonApi;
|
||||
|
||||
public Pseudocryptography(JsonApi jsonApi) {
|
||||
this.jsonApi = jsonApi;
|
||||
}
|
||||
|
||||
private Object prossed(Object object) {
|
||||
if (object instanceof Map) {
|
||||
System.out.println(object.getClass());
|
||||
val map = new HashMap<>((Map<Object, Object>) object);
|
||||
val map2 = new HashMap<>(map.size() + 3);
|
||||
map.forEach((key, value) -> {
|
||||
if (key instanceof String) {
|
||||
map2.put(prossed(key), prossed(value));
|
||||
}
|
||||
});
|
||||
|
||||
return map2;
|
||||
} else if (object instanceof String) {
|
||||
return StringUtil.stringToUnicode((String) object);
|
||||
} else if (object instanceof List) {
|
||||
ForEach.forEach((List<Object>) object, (t, i) -> {
|
||||
((List<Object>) object).set(i, prossed(t));
|
||||
});
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public void decode(String path) {
|
||||
try {
|
||||
final Map<String, Object> map = jsonApi.parseFrom(
|
||||
path,
|
||||
new JsonTypeReference<HashMap<String, Object>>() {}
|
||||
);
|
||||
|
||||
String s = jsonApi.format(prossed(map)).replace("\\\\u", "\\u");
|
||||
FileUtil.writeStringToFile(StringUtil.format("old-{}", path), s);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
279
src/main/java/com/mingliqiye/utils/stream/InOutSteam.java
Normal file
279
src/main/java/com/mingliqiye/utils/stream/InOutSteam.java
Normal file
@ -0,0 +1,279 @@
|
||||
package com.mingliqiye.utils.stream;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* 自定义的输入输出流工具类,支持线程安全的数据读写操作。<br>
|
||||
* 谁闲着没事干用本地输入输出<br>
|
||||
* 实现了 AutoCloseable、Closeable 和 Flushable 接口,便于资源管理。
|
||||
*
|
||||
* @author MingLiPro
|
||||
*/
|
||||
public class InOutSteam implements AutoCloseable, Closeable, Flushable {
|
||||
|
||||
private final Lock lock = new ReentrantLock();
|
||||
|
||||
List<Byte> bytes;
|
||||
|
||||
/**
|
||||
* 从内部缓冲区中读取最多 len 个字节到指定的字节数组 b 中。
|
||||
*
|
||||
* @param b 目标字节数组,用于存储读取的数据
|
||||
* @param off 起始偏移位置
|
||||
* @param len 最大读取字节数
|
||||
* @return 实际读取的字节数;如果已到达流末尾,则返回 -1
|
||||
* @throws IndexOutOfBoundsException 如果 off 或 len 参数非法
|
||||
*/
|
||||
public int read(byte@NotNull [] b, int off, int len) {
|
||||
if (bytes == null) return -1;
|
||||
if (bytes.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (off < 0 || len < 0 || off + len > b.length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
try {
|
||||
lock.lock();
|
||||
int bytesRead = Math.min(len, bytes.size());
|
||||
|
||||
for (int i = 0; i < bytesRead; i++) {
|
||||
b[off + i] = bytes.get(i);
|
||||
}
|
||||
if (bytesRead > 0) {
|
||||
bytes.subList(0, bytesRead).clear();
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取一个字节的数据。
|
||||
*
|
||||
* @return 下一个字节数据(0~255),如果已到达流末尾则返回 -1
|
||||
*/
|
||||
public int read() {
|
||||
if (bytes == null) return -1;
|
||||
try {
|
||||
lock.lock();
|
||||
if (bytes.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
return bytes.remove(0);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从内部缓冲区中读取最多 b.length 个字节到指定的字节数组 b 中。
|
||||
*
|
||||
* @param b 目标字节数组,用于存储读取的数据
|
||||
* @return 实际读取的字节数;如果已到达流末尾,则返回 -1
|
||||
*/
|
||||
public int read(byte@NotNull [] b) {
|
||||
if (bytes == null) return -1;
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳过并丢弃此输入流中数据的 n 个字节。
|
||||
*
|
||||
* @param n 要跳过的字节数
|
||||
* @return 实际跳过的字节数
|
||||
*/
|
||||
public long skip(long n) {
|
||||
if (bytes == null) return -1;
|
||||
if (bytes.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
lock.lock();
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
long bytesToSkip = Math.min(n, bytes.size());
|
||||
|
||||
// 移除跳过的字节
|
||||
if (bytesToSkip > 0) {
|
||||
bytes.subList(0, (int) bytesToSkip).clear();
|
||||
}
|
||||
|
||||
return bytesToSkip;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
|
||||
*
|
||||
* @return 可以无阻塞读取的字节数
|
||||
*/
|
||||
public int available() {
|
||||
if (bytes == null) return -1;
|
||||
try {
|
||||
lock.lock();
|
||||
return bytes.size();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取与当前对象关联的 InputStream 实例。
|
||||
*
|
||||
* @return InputStream 实例
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
if (inputStream == null) {
|
||||
inputStream = inputStream();
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
private InputStream inputStream;
|
||||
private OutputStream outputStream;
|
||||
|
||||
/**
|
||||
* 获取与当前对象关联的 OutputStream 实例。
|
||||
*
|
||||
* @return OutputStream 实例
|
||||
*/
|
||||
public OutputStream getOutputStream() {
|
||||
if (outputStream == null) {
|
||||
outputStream = outputStream();
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回一个包装后的 InputStream 实例。
|
||||
*
|
||||
* @return 新创建的 InputStream 实例
|
||||
*/
|
||||
private InputStream inputStream() {
|
||||
return new InputStreanWrapper(
|
||||
new InputStream() {
|
||||
@Override
|
||||
public int read() {
|
||||
return InOutSteam.this.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte@NotNull [] b, int off, int len) {
|
||||
return InOutSteam.this.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) {
|
||||
return InOutSteam.this.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return InOutSteam.this.available();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回一个 OutputStream 实例。
|
||||
*
|
||||
* @return 新创建的 OutputStream 实例
|
||||
*/
|
||||
private OutputStream outputStream() {
|
||||
return new OutputStream() {
|
||||
@Override
|
||||
public void write(int b) {
|
||||
InOutSteam.this.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte@NotNull [] b, int off, int len) {
|
||||
InOutSteam.this.write(b, off, len);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数,初始化内部字节列表。
|
||||
*/
|
||||
public InOutSteam() {
|
||||
bytes = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定的字节写入此输出流。
|
||||
*
|
||||
* @param b 要写入的字节
|
||||
*/
|
||||
public void write(int b) {
|
||||
try {
|
||||
lock.lock();
|
||||
bytes.add((byte) b);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定字节数组中的部分数据写入此输出流。
|
||||
*
|
||||
* @param b 数据源字节数组
|
||||
* @param off 起始偏移位置
|
||||
* @param len 写入的字节数
|
||||
* @throws IndexOutOfBoundsException 如果 off 或 len 参数非法
|
||||
*/
|
||||
public void write(byte@NotNull [] b, int off, int len) {
|
||||
if (off < 0 || len < 0 || off + len > b.length) {
|
||||
throw new IndexOutOfBoundsException("Invalid offset or length");
|
||||
}
|
||||
|
||||
try {
|
||||
lock.lock();
|
||||
for (int i = off; i < off + len; i++) {
|
||||
bytes.add(b[i]);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将整个字节数组写入此输出流。
|
||||
*
|
||||
* @param b 要写入的字节数组
|
||||
*/
|
||||
public void write(byte@NotNull [] b) {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新此输出流并强制写出所有缓冲的输出字节。
|
||||
* 当前实现为空方法。
|
||||
*/
|
||||
@Override
|
||||
public void flush() {}
|
||||
|
||||
/**
|
||||
* 关闭此流并释放与其相关的所有资源。
|
||||
* 清空并置空内部字节列表。
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
bytes.clear();
|
||||
bytes = null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package com.mingliqiye.utils.stream;
|
||||
|
||||
import com.mingliqiye.utils.collection.Lists;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import lombok.val;
|
||||
|
||||
/**
|
||||
* 输入流工具类,提供对InputStream的常用操作封装
|
||||
*/
|
||||
public class InputStreamUtils {
|
||||
|
||||
/**
|
||||
* 默认缓冲区大小:1MB
|
||||
*/
|
||||
public static final int DEFAULT_BUFFER_SIZE = 1024 * 1024;
|
||||
|
||||
/**
|
||||
* 将输入流读取到字节数组中<br>
|
||||
* 请在外部自行关闭输入流对象 避免资源泄露
|
||||
*
|
||||
* @param inputStream 输入流对象,用于读取数据
|
||||
* @return 包含输入流所有数据的字节数组
|
||||
* @throws IOException 当读取输入流或写入输出流时发生IO异常
|
||||
*/
|
||||
public static byte[] readToArray(InputStream inputStream)
|
||||
throws IOException {
|
||||
// 使用ByteArrayOutputStream来收集输入流中的所有数据
|
||||
try (val byteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||
val bytes = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int length;
|
||||
// 循环读取输入流数据,直到读取完毕
|
||||
while ((length = inputStream.read(bytes)) != -1) {
|
||||
byteArrayOutputStream.write(bytes, 0, length);
|
||||
}
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将输入流读取到Byte列表中<br>
|
||||
* 请在外部自行关闭输入流对象 避免资源泄露
|
||||
*
|
||||
* @param inputStream 输入流对象,用于读取数据
|
||||
* @return 包含输入流所有数据的Byte列表
|
||||
* @throws IOException 当读取输入流时发生IO异常
|
||||
*/
|
||||
public static List<Byte> readToList(InputStream inputStream)
|
||||
throws IOException {
|
||||
return Lists.toList(readToArray(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将输入流读取为字符串<br>
|
||||
* 请在外部自行关闭输入流对象 避免资源泄露
|
||||
* @param inputStream 输入流对象,用于读取数据
|
||||
* @return 输入流对应的字符串内容
|
||||
* @throws IOException 当读取输入流时发生IO异常
|
||||
*/
|
||||
public static String readToString(InputStream inputStream)
|
||||
throws IOException {
|
||||
return new String(readToArray(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将输入流的数据传输到输出流中<br>
|
||||
* 请在外部自行关闭输入流输出流对象 避免资源泄露
|
||||
*
|
||||
* @param inputStream 源输入流,用于读取数据
|
||||
* @param outputStream 目标输出流,用于写入数据
|
||||
* @return 传输的总字节数
|
||||
* @throws IOException 当读取或写入流时发生IO异常
|
||||
*/
|
||||
public static long transferTo(
|
||||
InputStream inputStream,
|
||||
OutputStream outputStream
|
||||
) throws IOException {
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("inputStream can not be null");
|
||||
}
|
||||
if (outputStream == null) {
|
||||
throw new IllegalArgumentException("outputStream can not be null");
|
||||
}
|
||||
val bytes = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int length;
|
||||
long readAll = 0L;
|
||||
// 循环读取并写入数据,直到输入流读取完毕
|
||||
while ((length = inputStream.read(bytes)) != -1) {
|
||||
outputStream.write(bytes, 0, length);
|
||||
readAll += length;
|
||||
}
|
||||
outputStream.flush();
|
||||
return readAll;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package com.mingliqiye.utils.stream;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class InputStreanWrapper extends InputStream implements AutoCloseable {
|
||||
|
||||
@Getter
|
||||
private final InputStream inputStream;
|
||||
|
||||
public InputStreanWrapper(InputStream inputStream) {
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
private static InputStreanWrapper of(InputStream inputStream) {
|
||||
return new InputStreanWrapper(inputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return inputStream.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return inputStream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte@NotNull [] b) throws IOException {
|
||||
return inputStream.read(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte@NotNull [] b, int off, int len) throws IOException {
|
||||
return inputStream.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return inputStream.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readlimit) {
|
||||
inputStream.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
inputStream.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return inputStream.markSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入流转换为输出流 <br>
|
||||
* jdk8 兼容实现 jdk9+ <br>
|
||||
* 请使用 InputStream.transferTo()
|
||||
*
|
||||
* @param outputStream
|
||||
* @return 转换的字节数
|
||||
* @throws IOException
|
||||
*/
|
||||
public long transferToOutputStream(OutputStream outputStream)
|
||||
throws IOException {
|
||||
return InputStreamUtils.transferTo(inputStream, outputStream);
|
||||
}
|
||||
|
||||
public byte[] readToArray() throws IOException {
|
||||
return InputStreamUtils.readToArray(inputStream);
|
||||
}
|
||||
|
||||
public List<Byte> readToList() throws IOException {
|
||||
return InputStreamUtils.readToList(inputStream);
|
||||
}
|
||||
|
||||
public String readToString() throws IOException {
|
||||
return InputStreamUtils.readToString(inputStream);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package com.mingliqiye.utils.stream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class OutputStreamWrapper extends OutputStream implements AutoCloseable {
|
||||
|
||||
@Getter
|
||||
private final OutputStream outputStream;
|
||||
|
||||
private final ByteArrayOutputStream byteArrayOutputStream =
|
||||
new ByteArrayOutputStream();
|
||||
|
||||
public OutputStreamWrapper(OutputStream outputStream) {
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
public static OutputStreamWrapper of(OutputStream outputStream) {
|
||||
return new OutputStreamWrapper(outputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
byteArrayOutputStream.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte@NotNull [] b) throws IOException {
|
||||
byteArrayOutputStream.write(b);
|
||||
}
|
||||
|
||||
public void write(List<Byte> b) throws IOException {
|
||||
write(b, 0, b.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte@NotNull [] b, int off, int len) throws IOException {
|
||||
byteArrayOutputStream.write(b, off, len);
|
||||
}
|
||||
|
||||
public void write(List<Byte> b, int off, int len) throws IOException {
|
||||
byte[] bytes = new byte[b.size()];
|
||||
for (int i = 0; i < b.size(); i++) {
|
||||
bytes[i] = b.get(i);
|
||||
}
|
||||
byteArrayOutputStream.write(bytes, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
outputStream.write(byteArrayOutputStream.toByteArray());
|
||||
byteArrayOutputStream.reset();
|
||||
}
|
||||
|
||||
public int getBufferCachedSize() {
|
||||
return byteArrayOutputStream.size();
|
||||
}
|
||||
|
||||
public byte[] getBufferCachedBytes() {
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public long transferFromOutputStream(InputStream inputStream)
|
||||
throws IOException {
|
||||
return InputStreamUtils.transferTo(inputStream, outputStream);
|
||||
}
|
||||
}
|
||||
1411
src/main/java/com/mingliqiye/utils/stream/SuperStream.java
Normal file
1411
src/main/java/com/mingliqiye/utils/stream/SuperStream.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -212,4 +212,60 @@ public class StringUtil {
|
||||
public static StringBuilder stringBuilder(int i) {
|
||||
return new StringBuilder(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转换为Unicode编码格式
|
||||
*
|
||||
* @param str 待转换的字符串
|
||||
* @return 转换后的Unicode编码字符串,每个字符都以\\u开头的十六进制形式表示
|
||||
*/
|
||||
public static String stringToUnicode(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char[] c = str.toCharArray();
|
||||
for (char value : c) {
|
||||
sb.append(stringToUnicode(value));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符转换为Unicode转义字符串
|
||||
*
|
||||
* @param c 需要转换的字符
|
||||
* @return 返回格式为"\\uXXXX"的Unicode转义字符串,其中XXXX为字符的十六进制Unicode码点
|
||||
*/
|
||||
public static String stringToUnicode(char c) {
|
||||
return "\\u" + String.format("%04x", (int) c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将整数转换为Unicode字符串表示形式
|
||||
*
|
||||
* @param c 要转换的整数,表示Unicode码点
|
||||
* @return 返回格式为"\\uXXXX"的Unicode字符串,其中XXXX是参数c的十六进制表示
|
||||
*/
|
||||
public static String stringToUnicode(Integer c) {
|
||||
return "\\u" + Integer.toHexString(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Unicode编码字符串转换为普通字符串
|
||||
* 该函数接收一个包含Unicode转义序列的字符串,将其解析并转换为对应的字符序列
|
||||
*
|
||||
* @param unicode 包含Unicode转义序列的字符串,格式如"\\uXXXX",其中XXXX为十六进制数
|
||||
* @return 转换后的普通字符串,包含对应的Unicode字符
|
||||
*/
|
||||
public static String unicodeToString(String unicode) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// 按照Unicode转义符分割字符串,得到包含十六进制编码的数组
|
||||
String[] hex = unicode.split("\\\\u");
|
||||
// 从索引1开始遍历,因为分割后的第一个元素是转义符前面的内容(可能为空)
|
||||
for (int i = 1; i < hex.length; i++) {
|
||||
// 将十六进制字符串转换为整数,作为字符的Unicode码点
|
||||
int index = Integer.parseInt(hex[i], 16);
|
||||
// 将Unicode码点转换为对应字符并添加到结果中
|
||||
sb.append((char) index);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile UUID.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* LastUpdate 2025-09-10 11:14:27
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
@ -58,10 +58,14 @@ public class UUID implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造一个基于当前时间的时间戳型 UUID(版本1)。
|
||||
* 构造一个基于当前时间的时间戳型 UUID(版本1)。<br>
|
||||
* 由于springboot 默认使用此构造函数构造UUID 导致致命BUG 废弃<br>
|
||||
* 下个大版本删除<br>
|
||||
* @deprecated 请使用 <code>UUID.getTimeBased()</code>
|
||||
*/
|
||||
@Deprecated
|
||||
public UUID() {
|
||||
uuid = UuidCreator.getTimeBased();
|
||||
uuid = UUID.getTimeBased().GetUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,6 +86,15 @@ public class UUID implements Serializable {
|
||||
this.uuid = java.util.UUID.fromString(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个基于当前时间生成的时间戳型 UUID(版本1)。
|
||||
*
|
||||
* @return 时间戳型 UUID
|
||||
*/
|
||||
public static UUID getTimeBased() {
|
||||
return new UUID(UuidCreator.getTimeBased());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为 UUID 实例。
|
||||
*
|
||||
@ -110,10 +123,7 @@ public class UUID implements Serializable {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
java.util.UUID uuid1 = java.util.UUID.fromString(data);
|
||||
UUID uuid = new UUID();
|
||||
uuid.setUuid(uuid1);
|
||||
return uuid;
|
||||
return new UUID(java.util.UUID.fromString(data));
|
||||
} catch (Exception e) {
|
||||
throw new UUIDException(e.getMessage(), e);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user