diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6d5a06c4..05f166a1c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@
* 【db 】 Column中加入columnDef字段默认值(issue#I3J6BG@Gitee)
* 【core 】 BeanUtil增加copyToList方法(issue#1526@Github)
* 【extra 】 MailAccount增加customProperty可以用户自定义属性(pr#317@Gitee)
+* 【system 】 SystemUtil.getUserInfo()中所有平台路径统一末尾加/(issue#I3NM39@Gitee)
### 🐞Bug修复
* 【db 】 修复SQL分页时未使用别名导致的错误,同时count时取消order by子句(issue#I3IJ8X@Gitee)
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
index b0a988056..e2d0fda40 100644
--- a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
@@ -78,6 +78,17 @@ public class FileUtil extends PathUtil {
* 当Path为文件形式时, path会加入一个表示文件的前缀
*/
public static final String PATH_FILE_PRE = URLUtil.FILE_URL_PREFIX;
+ /**
+ * 文件路径分隔符
+ * 在Unix和Linux下 是{@code '/'}; 在Windows下是 {@code '\'}
+ */
+ public static final String FILE_SEPARATOR = File.separator;
+ /**
+ * 多个PATH之间的分隔符
+ * 在Unix和Linux下 是{@code ':'}; 在Windows下是 {@code ';'}
+ */
+ public static final String PATH_SEPARATOR = File.pathSeparator;
+
/**
* 是否为Windows环境
diff --git a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
index 6c721232d..d07b3c408 100644
--- a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
@@ -1607,18 +1607,10 @@ public class CharSequenceUtil {
* @param str 字符串
* @param prefix 前缀
* @return 补充后的字符串
+ * @see #prependIfMissing(CharSequence, CharSequence, CharSequence...)
*/
public static String addPrefixIfNot(CharSequence str, CharSequence prefix) {
- if (isEmpty(str) || isEmpty(prefix)) {
- return str(str);
- }
-
- final String str2 = str.toString();
- final String prefix2 = prefix.toString();
- if (false == str2.startsWith(prefix2)) {
- return prefix2.concat(str2);
- }
- return str2;
+ return prependIfMissing(str, prefix, prefix);
}
/**
@@ -1627,18 +1619,10 @@ public class CharSequenceUtil {
* @param str 字符串
* @param suffix 后缀
* @return 补充后的字符串
+ * @see #appendIfMissing(CharSequence, CharSequence, CharSequence...)
*/
public static String addSuffixIfNot(CharSequence str, CharSequence suffix) {
- if (isEmpty(str) || isEmpty(suffix)) {
- return str(str);
- }
-
- final String str2 = str.toString();
- final String suffix2 = suffix.toString();
- if (false == str2.endsWith(suffix2)) {
- return str2.concat(suffix2);
- }
- return str2;
+ return appendIfMissing(str, suffix, suffix);
}
// ------------------------------------------------------------------------ split
@@ -3363,7 +3347,7 @@ public class CharSequenceUtil {
* @return 如果已经结尾,返回原字符串,否则返回添加结尾的字符串
* @since 3.0.7
*/
- public static String appendIfMissing(final CharSequence str, final CharSequence suffix, final CharSequence... suffixes) {
+ public static String appendIfMissing(CharSequence str, CharSequence suffix, CharSequence... suffixes) {
return appendIfMissing(str, suffix, false, suffixes);
}
@@ -3377,27 +3361,27 @@ public class CharSequenceUtil {
* @return 如果已经结尾,返回原字符串,否则返回添加结尾的字符串
* @since 3.0.7
*/
- public static String appendIfMissingIgnoreCase(final CharSequence str, final CharSequence suffix, final CharSequence... suffixes) {
+ public static String appendIfMissingIgnoreCase(CharSequence str, CharSequence suffix, CharSequence... suffixes) {
return appendIfMissing(str, suffix, true, suffixes);
}
/**
* 如果给定字符串不是以给定的一个或多个字符串为结尾,则在尾部添加结尾字符串
*
- * @param str 被检查的字符串
- * @param suffix 需要添加到结尾的字符串
- * @param ignoreCase 检查结尾时是否忽略大小写
- * @param suffixes 需要额外检查的结尾字符串,如果以这些中的一个为结尾,则不再添加
+ * @param str 被检查的字符串
+ * @param suffix 需要添加到结尾的字符串,不参与检查匹配
+ * @param ignoreCase 检查结尾时是否忽略大小写
+ * @param testSuffixes 需要额外检查的结尾字符串,如果以这些中的一个为结尾,则不再添加
* @return 如果已经结尾,返回原字符串,否则返回添加结尾的字符串
* @since 3.0.7
*/
- public static String appendIfMissing(final CharSequence str, final CharSequence suffix, final boolean ignoreCase, final CharSequence... suffixes) {
+ public static String appendIfMissing(CharSequence str, CharSequence suffix, boolean ignoreCase, CharSequence... testSuffixes) {
if (str == null || isEmpty(suffix) || endWith(str, suffix, ignoreCase)) {
return str(str);
}
- if (suffixes != null && suffixes.length > 0) {
- for (final CharSequence s : suffixes) {
- if (endWith(str, s, ignoreCase)) {
+ if (ArrayUtil.isNotEmpty(testSuffixes)) {
+ for (final CharSequence testSuffix : testSuffixes) {
+ if (endWith(str, testSuffix, ignoreCase)) {
return str.toString();
}
}
@@ -3415,7 +3399,7 @@ public class CharSequenceUtil {
* @return 如果已经结尾,返回原字符串,否则返回添加结尾的字符串
* @since 3.0.7
*/
- public static String prependIfMissing(final CharSequence str, final CharSequence prefix, final CharSequence... prefixes) {
+ public static String prependIfMissing(CharSequence str, CharSequence prefix, CharSequence... prefixes) {
return prependIfMissing(str, prefix, false, prefixes);
}
@@ -3429,7 +3413,7 @@ public class CharSequenceUtil {
* @return 如果已经结尾,返回原字符串,否则返回添加结尾的字符串
* @since 3.0.7
*/
- public static String prependIfMissingIgnoreCase(final CharSequence str, final CharSequence prefix, final CharSequence... prefixes) {
+ public static String prependIfMissingIgnoreCase(CharSequence str, CharSequence prefix, CharSequence... prefixes) {
return prependIfMissing(str, prefix, true, prefixes);
}
@@ -3443,7 +3427,7 @@ public class CharSequenceUtil {
* @return 如果已经结尾,返回原字符串,否则返回添加结尾的字符串
* @since 3.0.7
*/
- public static String prependIfMissing(final CharSequence str, final CharSequence prefix, final boolean ignoreCase, final CharSequence... prefixes) {
+ public static String prependIfMissing(CharSequence str, CharSequence prefix, boolean ignoreCase, CharSequence... prefixes) {
if (str == null || isEmpty(prefix) || startWith(str, prefix, ignoreCase)) {
return str(str);
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java
new file mode 100644
index 000000000..191e31137
--- /dev/null
+++ b/hutool-core/src/test/java/cn/hutool/core/text/CharSequenceUtilTest.java
@@ -0,0 +1,27 @@
+package cn.hutool.core.text;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CharSequenceUtilTest {
+
+ @Test
+ public void addPrefixIfNotTest(){
+ String str = "hutool";
+ String result = CharSequenceUtil.addPrefixIfNot(str, "hu");
+ Assert.assertEquals(str, result);
+
+ result = CharSequenceUtil.addPrefixIfNot(str, "Good");
+ Assert.assertEquals("Good" + str, result);
+ }
+
+ @Test
+ public void addSuffixIfNotTest(){
+ String str = "hutool";
+ String result = CharSequenceUtil.addSuffixIfNot(str, "tool");
+ Assert.assertEquals(str, result);
+
+ result = CharSequenceUtil.addSuffixIfNot(str, " is Good");
+ Assert.assertEquals( str + " is Good", result);
+ }
+}
diff --git a/hutool-system/src/main/java/cn/hutool/system/SystemUtil.java b/hutool-system/src/main/java/cn/hutool/system/SystemUtil.java
index 0fd6f472f..fe27b9b1e 100644
--- a/hutool-system/src/main/java/cn/hutool/system/SystemUtil.java
+++ b/hutool-system/src/main/java/cn/hutool/system/SystemUtil.java
@@ -1,5 +1,10 @@
package cn.hutool.system;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.lang.Singleton;
+import cn.hutool.core.util.StrUtil;
+
import java.io.PrintWriter;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
@@ -14,11 +19,6 @@ import java.lang.management.ThreadMXBean;
import java.util.List;
import java.util.Properties;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.lang.Console;
-import cn.hutool.core.lang.Singleton;
-import cn.hutool.core.util.StrUtil;
-
/**
* Java的System类封装工具类。
* 参考:http://blog.csdn.net/zhongweijian/article/details/7619383
@@ -168,7 +168,7 @@ public class SystemUtil {
* 取得系统属性,如果因为Java安全的限制而失败,则将错误打在Log中,然后返回 {@code null}
*
* @param name 属性名
- * @param quiet 安静模式,不将出错信息打在System.err
中
+ * @param quiet 安静模式,不将出错信息打在{@code System.err}中
* @return 属性值或{@code null}
* @see System#getProperty(String)
* @see System#getenv(String)
@@ -312,9 +312,9 @@ public class SystemUtil {
/**
* 返回Java虚拟机编译系统相关属性
- * 如果没有编译系统,则返回null
+ * 如果没有编译系统,则返回{@code null}
*
- * @return a {@link CompilationMXBean} ,如果没有编译系统,则返回null
+ * @return a {@link CompilationMXBean} ,如果没有编译系统,则返回{@code null}
* @since 4.1.4
*/
public static CompilationMXBean getCompilationMXBean() {
@@ -363,7 +363,7 @@ public class SystemUtil {
/**
* 取得Java Virtual Machine Specification的信息。
*
- * @return JvmSpecInfo
对象
+ * @return {@link JvmSpecInfo}对象
*/
public static JvmSpecInfo getJvmSpecInfo() {
return Singleton.get(JvmSpecInfo.class);
@@ -372,7 +372,7 @@ public class SystemUtil {
/**
* 取得Java Virtual Machine Implementation的信息。
*
- * @return JvmInfo
对象
+ * @return {@link JvmInfo}对象
*/
public static JvmInfo getJvmInfo() {
return Singleton.get(JvmInfo.class);
@@ -381,7 +381,7 @@ public class SystemUtil {
/**
* 取得Java Specification的信息。
*
- * @return JavaSpecInfo
对象
+ * @return {@link JavaSpecInfo}对象
*/
public static JavaSpecInfo getJavaSpecInfo() {
return Singleton.get(JavaSpecInfo.class);
@@ -390,7 +390,7 @@ public class SystemUtil {
/**
* 取得Java Implementation的信息。
*
- * @return JavaInfo
对象
+ * @return {@link JavaInfo}对象
*/
public static JavaInfo getJavaInfo() {
return Singleton.get(JavaInfo.class);
@@ -399,7 +399,7 @@ public class SystemUtil {
/**
* 取得当前运行的JRE的信息。
*
- * @return JreInfo
对象
+ * @return {@link JavaRuntimeInfo}对象
*/
public static JavaRuntimeInfo getJavaRuntimeInfo() {
return Singleton.get(JavaRuntimeInfo.class);
@@ -408,7 +408,7 @@ public class SystemUtil {
/**
* 取得OS的信息。
*
- * @return OsInfo
对象
+ * @return {@code OsInfo}对象
*/
public static OsInfo getOsInfo() {
return Singleton.get(OsInfo.class);
@@ -417,7 +417,7 @@ public class SystemUtil {
/**
* 取得User的信息。
*
- * @return UserInfo
对象
+ * @return {@code UserInfo}对象
*/
public static UserInfo getUserInfo() {
return Singleton.get(UserInfo.class);
@@ -426,7 +426,7 @@ public class SystemUtil {
/**
* 取得Host的信息。
*
- * @return HostInfo
对象
+ * @return {@link HostInfo}对象
*/
public static HostInfo getHostInfo() {
return Singleton.get(HostInfo.class);
@@ -435,7 +435,7 @@ public class SystemUtil {
/**
* 取得Runtime的信息。
*
- * @return RuntimeInfo
对象
+ * @return {@link RuntimeInfo}对象
*/
public static RuntimeInfo getRuntimeInfo() {
return Singleton.get(RuntimeInfo.class);
@@ -487,16 +487,16 @@ public class SystemUtil {
// ------------------------------------------------------------------ Dump
/**
- * 将系统信息输出到System.out
中。
+ * 将系统信息输出到{@link System#out}中。
*/
public static void dumpSystemInfo() {
dumpSystemInfo(new PrintWriter(System.out));
}
/**
- * 将系统信息输出到指定PrintWriter
中。
+ * 将系统信息输出到指定{@link PrintWriter}中。
*
- * @param out PrintWriter
输出流
+ * @param out {@link PrintWriter}输出流
*/
public static void dumpSystemInfo(PrintWriter out) {
out.println("--------------");
@@ -522,9 +522,9 @@ public class SystemUtil {
}
/**
- * 输出到StringBuilder
。
+ * 输出到{@link StringBuilder}。
*
- * @param builder StringBuilder
对象
+ * @param builder {@link StringBuilder}对象
* @param caption 标题
* @param value 值
*/
diff --git a/hutool-system/src/main/java/cn/hutool/system/UserInfo.java b/hutool-system/src/main/java/cn/hutool/system/UserInfo.java
index 86aa09f6f..7a52566b2 100644
--- a/hutool-system/src/main/java/cn/hutool/system/UserInfo.java
+++ b/hutool-system/src/main/java/cn/hutool/system/UserInfo.java
@@ -1,5 +1,8 @@
package cn.hutool.system;
+import cn.hutool.core.util.StrUtil;
+
+import java.io.File;
import java.io.Serializable;
/**
@@ -8,22 +11,37 @@ import java.io.Serializable;
public class UserInfo implements Serializable{
private static final long serialVersionUID = 1L;
- private final String USER_NAME = SystemUtil.get("user.name", false);
- private final String USER_HOME = SystemUtil.get("user.home", false);
- private final String USER_DIR = SystemUtil.get("user.dir", false);
- private final String USER_LANGUAGE = SystemUtil.get("user.language", false);
- private final String USER_COUNTRY = ((SystemUtil.get("user.country", false) == null) ? SystemUtil.get("user.region", false) : SystemUtil.get("user.country", false));
- private final String JAVA_IO_TMPDIR = SystemUtil.get("java.io.tmpdir", false);
+ private final String USER_NAME;
+ private final String USER_HOME;
+ private final String USER_DIR;
+ private final String JAVA_IO_TMPDIR;
+ private final String USER_LANGUAGE;
+ private final String USER_COUNTRY;
+
+ public UserInfo(){
+ USER_NAME = fixPath(SystemUtil.get("user.name", false));
+ USER_HOME = fixPath(SystemUtil.get("user.home", false));
+ USER_DIR = fixPath(SystemUtil.get("user.dir", false));
+ JAVA_IO_TMPDIR = fixPath(SystemUtil.get("java.io.tmpdir", false));
+ USER_LANGUAGE = SystemUtil.get("user.language", false);
+
+ // JDK1.4 {@code user.country},JDK1.2 {@code user.region}
+ String userCountry = SystemUtil.get("user.country", false);
+ if(null == userCountry){
+ userCountry = SystemUtil.get("user.country", false);
+ }
+ USER_COUNTRY = userCountry;
+ }
/**
- * 取得当前登录用户的名字(取自系统属性:user.name
)。
- *
+ * 取得当前登录用户的名字(取自系统属性:{@code user.name})。
+ *
*
- * 例如:"admin"
+ * 例如:{@code "admin"}
*
null
。
- *
+ *
+ * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
+ *
* @since Java 1.1
*/
public final String getName() {
@@ -31,14 +49,14 @@ public class UserInfo implements Serializable{
}
/**
- * 取得当前登录用户的home目录(取自系统属性:user.home
)。
- *
+ * 取得当前登录用户的home目录(取自系统属性:{@code user.home})。
+ *
*
- * 例如:"/home/admin"
+ * 例如:{@code "/home/admin/"}
*
null
。
- *
+ *
+ * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
+ *
* @since Java 1.1
*/
public final String getHomeDir() {
@@ -46,14 +64,14 @@ public class UserInfo implements Serializable{
}
/**
- * 取得当前目录(取自系统属性:user.dir
)。
- *
+ * 取得当前目录(取自系统属性:{@code user.dir})。
+ *
*
- * 例如:"/home/admin/working"
+ * 例如:{@code "/home/admin/working/"}
*
null
。
- *
+ *
+ * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
+ *
* @since Java 1.1
*/
public final String getCurrentDir() {
@@ -61,43 +79,43 @@ public class UserInfo implements Serializable{
}
/**
- * 取得临时目录(取自系统属性:java.io.tmpdir
)。
- *
+ * 取得临时目录(取自系统属性:{@code java.io.tmpdir})。
+ *
*
- * 例如:"/tmp"
+ * 例如:{@code "/tmp/"}
*
null
。
- *
- *
+ *
+ * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
+ *
+ *
*/
public final String getTempDir() {
return JAVA_IO_TMPDIR;
}
/**
- * 取得当前登录用户的语言设置(取自系统属性:user.language
)。
- *
+ * 取得当前登录用户的语言设置(取自系统属性:{@code user.language})。
+ *
*
- * 例如:"zh"
、"en"
等
+ * 例如:{@code "zh"}、{@code "en"}等
*
null
。
- *
+ *
+ * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
+ *
*/
public final String getLanguage() {
return USER_LANGUAGE;
}
/**
- * 取得当前登录用户的国家或区域设置(取自系统属性:JDK1.4 user.country
或JDK1.2 user.region
)。
- *
+ * 取得当前登录用户的国家或区域设置(取自系统属性:JDK1.4 {@code user.country}或JDK1.2 {@code user.region})。
+ *
*
- * 例如:"CN"
、"US"
等
+ * 例如:{@code "CN"}、{@code "US"}等
*
null
。
- *
+ *
+ * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
+ *
*/
public final String getCountry() {
return USER_COUNTRY;
@@ -105,7 +123,7 @@ public class UserInfo implements Serializable{
/**
* 将当前用户的信息转换成字符串。
- *
+ *
* @return 用户信息的字符串表示
*/
@Override
@@ -122,4 +140,17 @@ public class UserInfo implements Serializable{
return builder.toString();
}
+ /**
+ * 修正路径,包括:
+ *
+ *