add methods

This commit is contained in:
Looly 2021-08-02 20:16:04 +08:00
parent 72af4101bc
commit 08ebcad848
14 changed files with 209 additions and 32 deletions

View File

@ -11,6 +11,7 @@
* 【core 】 PhoneUtil中新增获取固话号码中区号,以及固话号码中号码的方法pr#387@Gitee
* 【json 】 JSONGetter增加getLocalDateTime方法pr#387@Gitee
* 【core 】 增加JNDIUtilissue#1727@Github
* 【core 】 NetUtil增加getDnsInfo方法issue#1727@Github
* 【core 】 SpringUtil增加unregisterBean方法pr#388@Gitee
* 【core 】 优化TextSimilarity公共子串算法issue#I42A6V@Gitee
* 【core 】 优化DateUtil.parse对UTC附带时区字符串解析issue#I437AP@Gitee
@ -20,6 +21,9 @@
* 【core 】 修复SpringUtil无法处理autowired问题pr#388@Gitee
* 【core 】 修复AbsCollValueMap中常量拼写错误pr#1736@Github
* 【core 】 修复FileUtil.del在文件只读情况下无法删除的问题pr#389@Gitee
* 【core 】 修复FileUtil.move在不同分区下失败的问题pr#390@Gitee
* 【core 】 修复FileUtil.copy强制覆盖参数无效问题
* 【core 】 修复NumberChineseFormatter转换金额多零问题issue#1739@Github
-------------------------------------------------------------------------------------------------------------

View File

@ -97,7 +97,7 @@ public class NumberChineseFormatter {
// TODO 此处逻辑过于复杂等待整理重构
if (i != 0) {
if (i % 2 == 0) {
if (parts[i - 1] < 1000) {
if (parts[i - 1] < 1000 && parts[i - 1] > 0) {
// 如果"亿"的部分不为 0, "亿"以下的部分小于 1000则亿后面应该跟如一亿零三十五万
chineseStr.insert(0, "");
}

View File

@ -4,6 +4,7 @@ import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.visitor.CopyVisitor;
import cn.hutool.core.io.file.visitor.DelVisitor;
import cn.hutool.core.io.file.visitor.MoveVisitor;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharsetUtil;
@ -16,7 +17,17 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.AccessDeniedException;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.EnumSet;
@ -221,7 +232,7 @@ public class PathUtil {
*/
public static Path copyContent(Path src, Path target, CopyOption... options) throws IORuntimeException {
try {
Files.walkFileTree(src, new CopyVisitor(src, target));
Files.walkFileTree(src, new CopyVisitor(src, target, options));
} catch (IOException e) {
throw new IORuntimeException(e);
}
@ -440,7 +451,8 @@ public class PathUtil {
/**
* 移动文件或目录<br>
* 当目标是目录时会将源文件或文件夹整体移动至目标目录下
* 当目标是目录时会将源文件或文件夹整体移动至目标目录下<br>
* 例如move("/usr/aaa", "/usr/bbb")结果为"/usr/bbb/aaa"
*
* @param src 源文件或目录路径
* @param target 目标路径如果为目录则移动到此目录下
@ -460,7 +472,15 @@ public class PathUtil {
try {
return Files.move(src, target, options);
} catch (IOException e) {
throw new IORuntimeException(e);
// 移动失败可能是跨分区移动导致的采用递归移动方式
try {
Files.walkFileTree(src, new MoveVisitor(src, target, options));
// 移动后空目录没有删除
del(src);
} catch (IOException e2) {
throw new IORuntimeException(e2);
}
return target;
}
}

View File

@ -3,6 +3,7 @@ package cn.hutool.core.io.file.visitor;
import cn.hutool.core.io.file.PathUtil;
import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@ -22,19 +23,22 @@ public class CopyVisitor extends SimpleFileVisitor<Path> {
private final Path source;
private final Path target;
private boolean isTargetCreated;
private final CopyOption[] copyOptions;
/**
* 构造
*
* @param source 源Path
* @param target 目标Path
* @param copyOptions 拷贝选项如跳过已存在等
*/
public CopyVisitor(Path source, Path target) {
public CopyVisitor(Path source, Path target, CopyOption... copyOptions) {
if(PathUtil.exists(target, false) && false == PathUtil.isDirectory(target)){
throw new IllegalArgumentException("Target must be a directory");
}
this.source = source;
this.target = target;
this.copyOptions = copyOptions;
}
@Override
@ -44,7 +48,7 @@ public class CopyVisitor extends SimpleFileVisitor<Path> {
// 将当前目录相对于源路径转换为相对于目标路径
final Path targetDir = target.resolve(source.relativize(dir));
try {
Files.copy(dir, targetDir);
Files.copy(dir, targetDir, copyOptions);
} catch (FileAlreadyExistsException e) {
if (false == Files.isDirectory(targetDir))
throw e;
@ -56,7 +60,7 @@ public class CopyVisitor extends SimpleFileVisitor<Path> {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
initTarget();
Files.copy(file, target.resolve(source.relativize(file)));
Files.copy(file, target.resolve(source.relativize(file)), copyOptions);
return FileVisitResult.CONTINUE;
}

View File

@ -0,0 +1,74 @@
package cn.hutool.core.io.file.visitor;
import cn.hutool.core.io.file.PathUtil;
import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
/**
* 文件移动操作的FileVisitor实现用于递归遍历移动目录和文件此类非线程安全<br>
* 此类在遍历源目录并移动过程中会自动创建目标目录中不存在的上级目录
*
* @author looly
* @since 5.7.7
*/
public class MoveVisitor extends SimpleFileVisitor<Path> {
private final Path source;
private final Path target;
private boolean isTargetCreated;
private final CopyOption[] copyOptions;
/**
* 构造
*
* @param source 源Path
* @param target 目标Path
*/
public MoveVisitor(Path source, Path target, CopyOption... copyOptions) {
if(PathUtil.exists(target, false) && false == PathUtil.isDirectory(target)){
throw new IllegalArgumentException("Target must be a directory");
}
this.source = source;
this.target = target;
this.copyOptions = copyOptions;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
initTarget();
// 将当前目录相对于源路径转换为相对于目标路径
final Path targetDir = target.resolve(source.relativize(dir));
if(false == Files.exists(targetDir)){
Files.createDirectories(targetDir);
} else if(false == Files.isDirectory(targetDir)){
throw new FileAlreadyExistsException(targetDir.toString());
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
initTarget();
Files.move(file, target.resolve(source.relativize(file)), copyOptions);
return FileVisitResult.CONTINUE;
}
/**
* 初始化目标文件或目录
*/
private void initTarget(){
if(false == this.isTargetCreated){
PathUtil.mkdir(this.target);
this.isTargetCreated = true;
}
}
}

View File

@ -1,13 +1,18 @@
package cn.hutool.core.net;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.EnumerationIter;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.JNDIUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
@ -823,6 +828,34 @@ public class NetUtil {
public static void setGlobalAuthenticator(Authenticator authenticator) {
Authenticator.setDefault(authenticator);
}
/**
* 获取DNS信息如TXT信息
*
* <pre class="code">
* NetUtil.attrNames("hutool.cn", "TXT")
* </pre>
*
* @param hostName 主机域名
* @param attrNames 属性
* @since 5.7.7
* @return DNS信息
*/
public static List<String> getDnsInfo(String hostName, String... attrNames){
final String uri = StrUtil.addPrefixIfNot(hostName, "dns:");
final Attributes attributes = JNDIUtil.getAttributes(uri, attrNames);
final List<String> infos = new ArrayList<>();
for (Attribute attribute: new EnumerationIter<>(attributes.getAll())){
try {
infos.add((String) attribute.get());
} catch (NamingException ignore) {
//ignore
}
}
return infos;
}
// ----------------------------------------------------------------------------------------- Private method start
/**

View File

@ -1,11 +1,10 @@
package cn.hutool.core.convert;
import java.util.concurrent.TimeUnit;
import cn.hutool.core.util.CharsetUtil;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.util.CharsetUtil;
import java.util.concurrent.TimeUnit;
/**
* 其它转换
@ -58,21 +57,6 @@ public class ConvertOtherTest {
Assert.assertEquals(75, minutes);
}
@Test
public void digitToChineseTest() {
double a = 67556.32;
String digitUppercase = Convert.digitToChinese(a);
Assert.assertEquals("陆万柒仟伍佰伍拾陆元叁角贰分", digitUppercase);
a = 1024.00;
digitUppercase = Convert.digitToChinese(a);
Assert.assertEquals("壹仟零贰拾肆元整", digitUppercase);
a = 1024;
digitUppercase = Convert.digitToChinese(a);
Assert.assertEquals("壹仟零贰拾肆元整", digitUppercase);
}
@Test
public void wrapUnwrapTest() {
// 去包装

View File

@ -83,6 +83,31 @@ public class NumberChineseFormatterTest {
Assert.assertEquals("贰仟肆佰贰拾壹元零贰分", digitToChinese3);
}
@Test
public void digitToChineseTest2() {
double a = 67556.32;
String digitUppercase = Convert.digitToChinese(a);
Assert.assertEquals("陆万柒仟伍佰伍拾陆元叁角贰分", digitUppercase);
a = 1024.00;
digitUppercase = Convert.digitToChinese(a);
Assert.assertEquals("壹仟零贰拾肆元整", digitUppercase);
a = 1024;
digitUppercase = Convert.digitToChinese(a);
Assert.assertEquals("壹仟零贰拾肆元整", digitUppercase);
}
@Test
public void digitToChineseTest3() {
String digitToChinese = Convert.digitToChinese(2_0000_0000.00);
Assert.assertEquals("贰亿元整", digitToChinese);
digitToChinese = Convert.digitToChinese(2_0000.00);
Assert.assertEquals("贰万元整", digitToChinese);
digitToChinese = Convert.digitToChinese(2_0000_0000_0000.00);
Assert.assertEquals("贰万亿元整", digitToChinese);
}
@Test
public void numberCharToChineseTest(){
String s = NumberChineseFormatter.numberCharToChinese('1', false);

View File

@ -44,6 +44,18 @@ public class PathUtilTest {
PathUtil.move(Paths.get("d:/lombok.jar"), Paths.get("d:/test/"), false);
}
@Test
@Ignore
public void moveDirTest(){
PathUtil.move(Paths.get("c:\\aaa"), Paths.get("d:/test/looly"), false);
}
@Test
@Ignore
public void delDirTest(){
PathUtil.del(Paths.get("d:/test/looly"));
}
@Test
@Ignore
public void getMimeTypeTest(){

View File

@ -1,5 +1,6 @@
package cn.hutool.core.net;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.ReUtil;
import org.junit.Assert;
@ -13,7 +14,7 @@ import java.util.List;
/**
* NetUtil单元测试
*
*
* @author Looly
*
*/
@ -93,4 +94,11 @@ public class NetUtilTest {
Assert.assertTrue(NetUtil.isOpen(address, 200));
}
@Test
@Ignore
public void getDnsInfoTest(){
final List<String> txt = NetUtil.getDnsInfo("hutool.cn", "TXT");
Console.log(txt);
}
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.lang.Console;
import org.junit.Ignore;
import org.junit.Test;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
@ -12,10 +13,10 @@ public class JNDIUtilTest {
@Test
@Ignore
public void getDnsTest(){
final Attributes attributes = JNDIUtil.getAttributes("dns:hutool.cn", "TXT");
public void getDnsTest() throws NamingException {
final Attributes attributes = JNDIUtil.getAttributes("dns:paypal.com", "TXT");
for (Attribute attribute: new EnumerationIter<>(attributes.getAll())){
Console.log(attribute);
Console.log(attribute.get());
}
}
}

View File

@ -31,7 +31,6 @@ import java.net.Proxy;
import java.net.URLStreamHandler;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**

View File

@ -8,7 +8,7 @@ import org.junit.Test;
/**
* Rest类型请求单元测试
*
*
* @author looly
*
*/
@ -52,4 +52,16 @@ public class RestTest {
.set("键2", "值2").toString());
Console.log(request.execute().body());
}
@Test
@Ignore
public void getWithBodyTest2() {
HttpRequest request = HttpRequest.get("https://ad.oceanengine.com/open_api/2/advertiser/info/")//
.setHttpProxy("localhost", 8888)
.header("Access-Token","b91e44f37ff2544079ceabcfafaf02bd3db9b769")
.body(JSONUtil.createObj()
.set("advertiser_ids", new Long[] {1690657248243790L})
.set("fields", new String[] {"id", "name", "status"}).toString());
Console.log(request.execute().body());
}
}

View File

@ -26,6 +26,7 @@ public class SimpleServerTest {
String res = JSONUtil.createObj()
.set("id", 1)
.set("method", request.getMethod())
.set("request", request.getBody())
.toStringPretty();
response.write(res, ContentType.JSON.toString());
})