no message
All checks were successful
Gitea Actions Build / Build (push) Successful in 53s

This commit is contained in:
Armamem0t 2025-09-10 20:58:17 +08:00
parent 0376ef3a9d
commit 09792e2c3b
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
92 changed files with 2552 additions and 1597 deletions

View File

@ -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"
}

View File

@ -22,4 +22,4 @@
JDKVERSIONS=1.8
GROUPSID=com.mingliqiye.utils
ARTIFACTID=mingli-utils
VERSIONS=3.0.1
VERSIONS=3.0.3

View File

@ -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

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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));
}

View File

@ -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

View 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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View 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>
* 实现了 AutoCloseableCloseable 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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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();
}
}

View File

@ -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);
}