This commit is contained in:
Looly
2022-07-29 23:05:20 +08:00
parent a36a970341
commit 7769822e11
17 changed files with 237 additions and 27 deletions

View File

@@ -60,7 +60,7 @@ public class CopyOptions implements Serializable {
*/
protected boolean transientSupport = true;
/**
* 是否覆盖目标值,如果不覆盖,会先读取目标对象的值,{@code null}则写,否则忽略。如果覆盖,则不判断直接写
* 是否覆盖目标值,如果不覆盖,会先读取目标对象的值,{@code null}则写,否则忽略。如果覆盖,则不判断直接写
*/
protected boolean override = true;
@@ -282,7 +282,7 @@ public class CopyOptions implements Serializable {
}
/**
* 设置是否覆盖目标值,如果不覆盖,会先读取目标对象的值,{@code null}则写,否则忽略。如果覆盖,则不判断直接写
* 设置是否覆盖目标值,如果不覆盖,会先读取目标对象的值,{@code null}则写,否则忽略。如果覆盖,则不判断直接写
*
* @param override 是否覆盖目标值
* @return this

View File

@@ -263,6 +263,10 @@ public class Base64 {
* @since 5.7.5
*/
public static boolean isBase64(final byte[] base64Bytes) {
if (base64Bytes == null || base64Bytes.length < 3) {
return false;
}
boolean hasPadding = false;
for (final byte base64Byte : base64Bytes) {
if (hasPadding) {

View File

@@ -29,6 +29,7 @@ import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.function.Consumer;
import java.util.zip.ZipEntry;
@@ -122,7 +123,7 @@ public class ZipUtil {
}
} catch (final FileAlreadyExistsException ignored) {
// 不覆盖情况下,文件已存在, 跳过
} catch (final IOException e){
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
@@ -260,6 +261,7 @@ public class ZipUtil {
*/
public static File zip(final File zipFile, final Charset charset, final boolean withSrcDir, final FileFilter filter, final File... srcFiles) throws IORuntimeException {
validateFiles(zipFile, srcFiles);
//noinspection resource
ZipWriter.of(zipFile, charset).add(withSrcDir, filter, srcFiles).close();
return zipFile;
}
@@ -412,6 +414,7 @@ public class ZipUtil {
* @since 5.5.2
*/
public static File zip(final File zipFile, final Charset charset, final Resource... resources) throws UtilException {
//noinspection resource
ZipWriter.of(zipFile, charset).add(resources).close();
return zipFile;
}
@@ -528,11 +531,38 @@ public class ZipUtil {
* @since 4.5.8
*/
public static File unzip(final ZipFile zipFile, final File outFile) throws IORuntimeException {
return unzip(zipFile, outFile, -1);
}
/**
* 限制解压后文件大小
*
* @param zipFile zip文件附带编码信息使用完毕自动关闭
* @param outFile 解压到的目录
* @param limit 限制解压文件大小(单位B)
* @return 解压的目录
* @throws IORuntimeException IO异常
* @since 5.8.5
*/
public static File unzip(ZipFile zipFile, File outFile, long limit) throws IORuntimeException {
if (outFile.exists() && outFile.isFile()) {
throw new IllegalArgumentException(
StrUtil.format("Target path [{}] exist!", outFile.getAbsolutePath()));
}
// pr#726@Gitee
if (limit > 0) {
final Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
long zipFileSize = 0L;
while (zipEntries.hasMoreElements()) {
ZipEntry zipEntry = zipEntries.nextElement();
zipFileSize += zipEntry.getSize();
if (zipFileSize > limit) {
throw new IllegalArgumentException("The file size exceeds the limit");
}
}
}
try (final ZipReader reader = new ZipReader(zipFile)) {
reader.readTo(outFile);
}

View File

@@ -605,19 +605,38 @@ public class Convert {
}
/**
* 转换为Map
* 转换为Map若value原本就是Map则转为原始类型若不是则默认转为HashMap
*
* @param <K> 键类型
* @param <V> 值类型
* @param keyType 键类型
* @param <K> 键类型
* @param <V> 值类型
* @param keyType 键类型
* @param valueType 值类型
* @param value 被转换的值
* @param value 被转换的值
* @return {@link Map}
* @since 4.6.8
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> toMap(final Class<K> keyType, final Class<V> valueType, final Object value) {
return (Map<K, V>) new MapConverter().convert(HashMap.class, keyType, valueType, value);
public static <K, V> Map<K, V> toMap(Class<K> keyType, Class<V> valueType, Object value) {
if (value instanceof Map) {
return toMap(value.getClass(), keyType, valueType, value);
} else {
return toMap(HashMap.class, keyType, valueType, value);
}
}
/**
* 转换为Map
*
* @param mapType 转后的具体Map类型
* @param <K> 键类型
* @param <V> 值类型
* @param keyType 键类型
* @param valueType 值类型
* @param value 被转换的值
* @return {@link Map}
*/
@SuppressWarnings({"unchecked"})
public static <K, V> Map<K, V> toMap(Class<?> mapType, Class<K> keyType, Class<V> valueType, Object value) {
return (Map<K, V>) MapConverter.INSTANCE.convert(mapType, keyType, valueType, value);
}
/**

View File

@@ -86,13 +86,13 @@ public class NetUtil {
/**
* 将IPv6地址字符串转为大整数
*
* @param IPv6Str 字符串
* @param ipv6Str 字符串
* @return 大整数, 如发生异常返回 null
* @since 5.5.7
*/
public static BigInteger ipv6ToBitInteger(final String IPv6Str) {
public static BigInteger ipv6ToBigInteger(final String ipv6Str) {
try {
final InetAddress address = InetAddress.getByName(IPv6Str);
final InetAddress address = InetAddress.getByName(ipv6Str);
if (address instanceof Inet6Address) {
return new BigInteger(1, address.getAddress());
}

View File

@@ -133,7 +133,7 @@ public class PatternPool {
/**
* 时间正则
*/
public static final Pattern TIME = Pattern.compile("\\d{1,2}:\\d{1,2}(:\\d{1,2})?");
public static final Pattern TIME = Pattern.compile(RegexPool.TIME);
/**
* 中国车牌号码(兼容新能源车牌)
*/

View File

@@ -64,4 +64,25 @@ public class BeanCopierTest {
private static class B {
private String value;
}
/**
* 为{@code null}则写,否则忽略。如果覆盖,则不判断直接写
*/
@Test
public void issues2484Test() {
final A a = new A();
a.setValue("abc");
final B b = new B();
b.setValue("123");
BeanCopier<B> copier = BeanCopier.of(a, b, CopyOptions.of().setOverride(false));
copier.copy();
Assert.assertEquals("123", b.getValue());
b.setValue(null);
copier = BeanCopier.of(a, b, CopyOptions.of().setOverride(false));
copier.copy();
Assert.assertEquals("abc", b.getValue());
}
}

View File

@@ -1,6 +1,7 @@
package cn.hutool.core.convert;
import cn.hutool.core.bean.BeanUtilTest.SubPerson;
import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.reflect.TypeReference;
import org.junit.Assert;
import org.junit.Test;
@@ -91,4 +92,30 @@ public class ConvertToBeanTest {
final SubPerson subPerson = Convert.convertQuietly(SubPerson.class, nullStr);
Assert.assertNull(subPerson);
}
@Test
public void mapToMapWithSelfTypeTest() {
final CaseInsensitiveMap<String, Integer> caseInsensitiveMap = new CaseInsensitiveMap<>();
caseInsensitiveMap.put("jerry", 1);
caseInsensitiveMap.put("Jerry", 2);
caseInsensitiveMap.put("tom", 3);
Map<String, String> map = Convert.toMap(String.class, String.class, caseInsensitiveMap);
Assert.assertEquals("2", map.get("jerry"));
Assert.assertEquals("2", map.get("Jerry"));
Assert.assertEquals("3", map.get("tom"));
}
@Test
public void beanToSpecifyMapTest() {
final SubPerson person = new SubPerson();
person.setAge(14);
person.setOpenid("11213232");
person.setName("测试A11");
person.setSubName("sub名字");
Map<String, String> map = Convert.toMap(LinkedHashMap.class, String.class, String.class, person);
Assert.assertEquals("测试A11", map.get("name"));
Assert.assertEquals("14", map.get("age"));
Assert.assertEquals("11213232", map.get("openid"));
}
}

View File

@@ -18,6 +18,7 @@ import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipFile;
/**
* {@link ZipUtil}单元测试
@@ -197,4 +198,19 @@ public class ZipUtilTest {
ZipUtil.zip(FileUtil.file("d:\\test\\qr.zip"),false,dd);
}
@Test
@Ignore
public void sizeUnzip() throws IOException {
String zipPath = "F:\\BaiduNetdiskDownload\\demo.zip";
String outPath = "F:\\BaiduNetdiskDownload\\test";
ZipFile zipFile = new ZipFile(zipPath, Charset.forName("GBK"));
File file = new File(outPath);
// 限制解压文件大小为637KB
long size = 637*1024L;
// 限制解压文件大小为636KB
// long size = 636*1024L;
ZipUtil.unzip(zipFile, file, size);
}
}