首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何按字节大小截断包含表情符号的字符串

如何按字节大小截断包含表情符号的字符串
EN

Stack Overflow用户
提问于 2015-10-08 03:34:07
回答 1查看 784关注 0票数 1

我希望将具有UTF-8字符集大小的字符串限制为30个字节,并找到了一个解决方案

因此,我在此基础上创建了一个方法

代码语言:javascript
运行
复制
public static String truncateTextByByteLimit(String message, int byteLimit) {
    String result = "";
    try {
        Charset utf8Charset = Charset.forName("UTF-8");
        CharsetDecoder cd = utf8Charset.newDecoder();
        byte[] utf8Bytes = message.getBytes(utf8Charset);
        System.out.println("check message: " + message + " /length: " +message.length()+ " //byte length: " + utf8Bytes.length + "/limit: " + byteLimit + " /codePoint: " +message.codePointCount(0, message.length()));
        ByteBuffer bb = ByteBuffer.wrap(utf8Bytes, 0, byteLimit);
        CharBuffer cb = CharBuffer.allocate(byteLimit);
        // Ignore an incomplete character
        cd.onMalformedInput(CodingErrorAction.IGNORE);
        cd.decode(bb, cb, true);
        cd.flush(cb);
        result = new String(cb.array(), 0, cb.position());
        if (result.length()<=0) {
            return truncateTextByByteLimit(message, (byteLimit+1));
        } else {
            return result;
        }
    } catch (Exception e) {
        e.printStackTrace();

        return message;
    }
}

问题是,当我使用表情符号测试字符串时,如下所示:System.out.println(truncateTextByByteLimit("let's \uD83D\uDE09", 30));

它显示出错误

代码语言:javascript
运行
复制
java.lang.IndexOutOfBoundsException
at java.nio.ByteBuffer.wrap(ByteBuffer.java:371)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

我的调试消息显示了check message: let's /length: 8 //byte length: 10/limit: 30 /codePoint: 7

当我用相同的消息和小于或等于10的byteLimit进行测试时,它没有错误.

所以我不明白为什么它会显示java.lang.IndexOutOfBoundsException

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-08 03:46:16

关于允许长度的ByteBuffer#wrap 有限度

要使用的子数组的长度;必须是非负的,且不大于array.length - offset.新缓冲区的限制将设置为offset + length

要解决这个问题,您需要采取两个长度中的较小的一个--要么是绝对的最大byteLimit,要么是utf8Bytes数组的大小。

代码语言:javascript
运行
复制
ByteBuffer.wrap(utf8Bytes, 0, Math.min(utf8Bytes.length, byteLimit));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33006160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档