mirror of
https://gitee.com/dromara/hutool.git
synced 2026-02-09 09:16:26 +08:00
修复StrUtil.truncateByByteLength在限制长度小于...时报错问题(issue#IDFTJS@Gitee)
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
* 【core 】 修复`SplitIter.reset`后无法重新迭代的问题(pr#1418@Gitee)
|
||||
* 【core 】 修复`StrMatcher`连续变量解析导致的歧义问题(pr#1419@Gitee)
|
||||
* 【ai 】 修复`BaseAIService`发送请求方法中try/catch块捕获的应该是Exception而不是自定义的AIException(pr#1430@Gitee)
|
||||
* 【core 】 修复`StrUtil.truncateByByteLength`在限制长度小于...时报错问题(issue#IDFTJS@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.42(2025-11-28)
|
||||
|
||||
@@ -288,7 +288,7 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return {@link String }
|
||||
* @author Junwei Xu
|
||||
* @author Junwei Xu
|
||||
*/
|
||||
public static String toStringOrEmpty(Object obj) {
|
||||
// obj为空时, 返回 null 或 "null" 都不适用部分场景, 此处返回 "" 空字符串
|
||||
@@ -379,6 +379,7 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
* 该方法按Unicode code point进行反转,支持Unicode字符的正确反转
|
||||
* 确保复杂字符不会被拆分,如表情符号等多字节字符
|
||||
* </p>
|
||||
*
|
||||
* @param str 被反转的字符串
|
||||
* @return 反转后的字符串,如果输入为null则返回null
|
||||
* @since 5.8.43
|
||||
@@ -536,29 +537,31 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
* 此方法用于截取总bytes数不超过指定长度,如果字符出没有超出原样输出,如果超出了,则截取掉超出部分,并可选添加...,
|
||||
* 但是添加“...”后总长度也不超过限制长度。
|
||||
*
|
||||
* @param str 原始字符串
|
||||
* @param charset 指定编码
|
||||
* @param maxBytes 最大字节数
|
||||
* @param factor 速算因子,取该编码下单个字符的最大可能字节数
|
||||
* @param appendDots 截断后是否追加省略号(...)
|
||||
* @param str 原始字符串
|
||||
* @param charset 指定编码
|
||||
* @param maxBytesLength 最大字节数
|
||||
* @param factor 速算因子,取该编码下单个字符的最大可能字节数
|
||||
* @param appendDots 截断后是否追加省略号...,如果maxBytesLength小于省略号长度,则不添加...
|
||||
* @return 截断后的字符串
|
||||
*/
|
||||
public static String truncateByByteLength(String str, Charset charset, int maxBytes, int factor,
|
||||
boolean appendDots) {
|
||||
public static String truncateByByteLength(String str, Charset charset, int maxBytesLength, int factor,
|
||||
boolean appendDots) {
|
||||
//字符数*速算因子<=最大字节数
|
||||
if (str == null || str.length() * factor <= maxBytes) {
|
||||
if (str == null || str.length() * factor <= maxBytesLength) {
|
||||
return str;
|
||||
}
|
||||
final byte[] sba = str.getBytes(charset);
|
||||
if (sba.length <= maxBytes) {
|
||||
if (sba.length <= maxBytesLength) {
|
||||
return str;
|
||||
}
|
||||
//限制字节数
|
||||
final int dotsBytesLength = "...".getBytes(charset).length;
|
||||
final int limitBytes;
|
||||
if (appendDots) {
|
||||
limitBytes = maxBytes - "...".getBytes(charset).length;
|
||||
// issue#IDFTJS 修正截断后追加省略号...导致超出限制长度的问题
|
||||
if (appendDots && maxBytesLength > dotsBytesLength) {
|
||||
limitBytes = maxBytesLength - "...".getBytes(charset).length;
|
||||
} else {
|
||||
limitBytes = maxBytes;
|
||||
limitBytes = maxBytesLength;
|
||||
}
|
||||
final ByteBuffer bb = ByteBuffer.wrap(sba, 0, limitBytes);
|
||||
final CharBuffer cb = CharBuffer.allocate(limitBytes);
|
||||
@@ -568,7 +571,7 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
decoder.decode(bb, cb, true);
|
||||
decoder.flush(cb);
|
||||
final String result = new String(cb.array(), 0, cb.position());
|
||||
if (appendDots) {
|
||||
if (appendDots && maxBytesLength > dotsBytesLength) {
|
||||
return result + "...";
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -719,4 +719,11 @@ public class StrUtilTest {
|
||||
final String ret = StrUtil.truncateByByteLength(str, StandardCharsets.ISO_8859_1, 10, 1, false);
|
||||
assertEquals("This is En", ret);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issueTest() {
|
||||
final String s = "abc";
|
||||
final String r = StrUtil.truncateByByteLength(s, CharsetUtil.CHARSET_UTF_8, 2, 4, true);
|
||||
assertEquals("ab", r);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user