From 723e495b3c575f6df71e5f65029d909cf5d7cd25 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 27 Dec 2025 13:05:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D`StrUtil.truncateByByteLength?= =?UTF-8?q?`=E5=9C=A8=E9=99=90=E5=88=B6=E9=95=BF=E5=BA=A6=E5=B0=8F?= =?UTF-8?q?=E4=BA=8E...=E6=97=B6=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=88issue#IDFTJS@Gitee=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../java/cn/hutool/core/util/StrUtil.java | 31 ++++++++++--------- .../java/cn/hutool/core/util/StrUtilTest.java | 7 +++++ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab527aff78..64c511ff1b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java index 19a6b703a1..43b9728061 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java @@ -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字符的正确反转 * 确保复杂字符不会被拆分,如表情符号等多字节字符 *

+ * * @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; diff --git a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java index f38a009bbf..b54d7eec9b 100755 --- a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java @@ -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); + } }