首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一旦UTF-8编码,如何截断一个java字符串以适应给定的字节数?

UTF-8 编码是 Unicode 编码的一种变体,它在内存和磁盘空间中占用字节数与具体字符密切相关。由于 UTF-8 编码具有变长的特性,当截断一个字符串时,我们无法确保精确按照指定字节数来进行截断,只能尽量保证截断后字符串的 Unicode 解析正确性。

以下是在 Java 中截断 UTF-8 字符串的一些建议:

  1. 如果要截断的字符串恰好不超过给定的字节数,可以直接使用 String 类型的 substring 方法来截取,如下面的示例所示:
代码语言:java
复制
String input = "Hello, 世界!";
int maxLength = 25;

String truncated = input.substring(0, maxLength);
  1. 如果要对字符串进行精确截断,则可以考虑先计算字符串所用字节的平均长度,然后乘以要截断的位数来得到指定字节数,并使用 ByteBuffer 对象从字符串的开始截取数据。

以下是一个简单的示例:

代码语言:java
复制
int maxLength = 25;
int bytesPerChar = ... 计算 UTF-8 编码的平均字节长度(这里假设平均字节长度为 4)
byte[] charset = ... 根据你的 Java 字符集和字节类型配置替换该字节数组

ByteBuffer buffer = ByteBuffer.allocate(maxLength * bytesPerChar).order(ByteOrder.LITTLE_ENDIAN);
buffer.putShort(0).putChar(0); // 初始化头信息
try {
    while (input.getBytes(charset).remaining() > maxLength*bytesPerChar) {
        int toSkip = Math.min(maxLength, input.getBytes(charset).remaining());
        buffer.position(buffer.position() - toSkip);
        input.getBytes(charset).skip(toSkip);
        int codePoint = ... 计算从当前位置到截断位置之间可能的最大 Unicode 字符字节
        if (buffer.get(0)) {
            // 如果之前未出现过该 Unicode 字符,说明本次截断正确
            input = input.substring(0, input.length() - (codePoint-0x3C));
        } else { // 如果之前出现过该 Unicode 字符, 说明此次截断错误,保留原有字符串
            input = input.substring(0, input.length());
            }
        ByteBuffer subBuffer = buffer.slice();
        if (subBuffer.position()< maxLength) {
            // 如果截断位置在截取范围内,则截取字符串
        } else { // 否则丢弃所有已经截断的 Unicode 字符后截取字符串
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • Java正确进行字符串编码转换

    字符串在java中统一用unicode表示( 即utf-16 LE) , 对于 String s = "你好哦!";如果源码文件是GBK编码, 操作系统(windows)默认的环境编码为GBK,那么编译时, JVM将按照GBK编码将字节数组解析成字符,然后将字符转换为unicode格式的字节数组,作为内部存储。当打印这个字符串时,JVM 根据操作系统本地的语言环境,将unicode转换为GBK,然后操作系统将GBK格式的内容显示出来。 当源码文件是UTF-8, 我们需要通知编译器源码的格式,javac -encoding utf-8 ... , 编译时,JVM按照utf-8 解析成字符,然后转换为unicode格式的字节数组, 那么不论源码文件是什么格式,同样的字符串,最后得到的unicode字节数组是完全一致的,显示的时候,也是转成GBK来显示(跟OS环境有关) 乱码如何产生?本质上都是由于字符串原本的编码格式与读取时解析用的编码格式不一致导致的。 例如:String s = "你好哦!"; System.out.println( new String(s.getBytes(),"UTF-8")); //错误,因为getBytes()默认使用GBK编码, 而解析时使用UTF-8编码,肯定出错。 其中 getBytes() 是将unicode 转换为操作系统默认的格式的字节数组,即"你好哦"的 GBK格式,new String (bytes, Charset) 中的charset 是指定读取 bytes 的方式,这里指定为UTF-8,即把bytes的内容当做UTF-8 格式对待。 如下两种方式都会有正确的结果,因为他们的源内容编码和解析用的编码是一致的。 System.out.println( new String(s.getBytes(),"GBK")); System.out.println( new String(s.getBytes("UTF-8"),"UTF-8")); 那么,如何利用getBytes 和 new String() 来进行编码转换呢? 网上流传着一种错误的方法:GBK--> UTF-8: new String( s.getBytes("GBK") , "UTF-8); ,这种方式是完全错误的,因为getBytes 的编码与 UTF-8 不一致,肯定是乱码。但是为什么在tomcat 下,使用new String(s.getBytes("iso-8859-1") ,"GBK") 却可以用呢?

    01

    Julia(字符串)

    字符串是字符的有限序列。当然,真正的麻烦来自于人们问一个角色是什么。英语演讲熟悉的字符是字母A,B,C等,用数字和常用标点符号在一起。这些字符通过ASCII标准进行了标准化,并映射到0到127之间的整数值。当然,还有许多其他非英语语言使用的字符,包括带有重音和其他修饰的ASCII字符变体,相关的脚本(例如西里尔字母和希腊语)以及与ASCII和英语完全无关的脚本,包括阿拉伯语,中文,希伯来语,北印度语,日语和韩语。该统一标准解决了一个字符的复杂性,通常被认为是解决该问题的权威标准。根据您的需要,您可以完全忽略这些复杂性,而假装仅存在ASCII字符,或者可以编写可以处理任何字符或处理非ASCII文本时可能遇到的编码的代码。Julia使处理普通ASCII文本简单而有效,而处理Unicode则尽可能简单而高效。特别是,您可以编写C样式的字符串代码来处理ASCII字符串,并且它们在性能和语义方面都将按预期工作。如果此类代码遇到非ASCII文本,它将以明确的错误消息正常地失败,而不是默默地引入损坏的结果。当这个情况发生时,

    01
    领券