mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-03 04:13:49 +08:00
add methods
This commit is contained in:
parent
72af4101bc
commit
08ebcad848
@ -11,6 +11,7 @@
|
||||
* 【core 】 PhoneUtil中新增获取固话号码中区号,以及固话号码中号码的方法(pr#387@Gitee)
|
||||
* 【json 】 JSONGetter增加getLocalDateTime方法(pr#387@Gitee)
|
||||
* 【core 】 增加JNDIUtil(issue#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)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -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, "零");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
74
hutool-core/src/main/java/cn/hutool/core/io/file/visitor/MoveVisitor.java
Executable file
74
hutool-core/src/main/java/cn/hutool/core/io/file/visitor/MoveVisitor.java
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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() {
|
||||
// 去包装
|
||||
|
@ -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);
|
||||
|
@ -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(){
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user