Java练习:如何分批次将UTF8字节转换中文字符

目标:分批次将UTF8字节转换中文字符

关键问题:

 1. UTF8中汉字占的字节数3-4个,因此需要注意分批时汉字被切割。
 2. “StandardCharsets.UTF_8”未成功解析的字节不会写入新的缓冲区中。
 3. 需要记录每次读取的位置。
 4. Arrays.copyOfRange会的to位置过大有可能会造成空读,超出部分它照样会创建空间。

思路:

  1. 分批次获取到字节的一部分,每次获取尽量不要小于5是最好的(最低也要3)。
  2. 利用字节缓冲区的position指针与limit指针计算出未成功读出的字节数,计入到下一次的读取中。

代码:

    @Test
    public void for_test_chinese() throws CharacterCodingException {
        var raw = "长坂桥头a杀气生,横枪立马b眼圆睁。一声好似c轰雷震,独退曹家d百万兵。";
        // 转转字节
        var rawBytes = StandardCharsets.UTF_8.encode(raw).array();

        // 总字节数
        int maxLength = rawBytes.length;
        // 每次读取字节数,值不能小于5,太小会导致一个字都读不出来
        int intervalSize = 6;
        // 缓冲区大小,不能小于每次读取字节数
        int bufferSize = 12;
        // 初始读取字节位置
        int nowLength = 0;

        while (maxLength > nowLength){
            int value = maxLength - nowLength;
            // 判断是否超出数据
            if (value < intervalSize){
                intervalSize = value;
            }

            // 分批解码UTF字节到字符串
            var rawBatchBytes = Arrays.copyOfRange(rawBytes, nowLength, intervalSize + nowLength);

            // 字节缓冲区
            var byteBuffer = ByteBuffer.allocate(bufferSize);
            // 将已提取的字节写入
            byteBuffer.put(rawBatchBytes);
            // 翻转进入读模式
            byteBuffer.flip();

            // 字符缓冲区
            var charBuffer = CharBuffer.allocate(bufferSize);
            // 转换字符,写入charBuffer。注意byteBuffer中无法解释的部分不会写入charBuffer,因此多出的字节不能计算
            StandardCharsets.UTF_8.newDecoder().decode(byteBuffer, charBuffer,true);
            // 翻转进入读模式
            charBuffer.flip();

            // 创建字符集合
            var tmp = new char[charBuffer.length()];
            // 判断charBuffer是否有数据
            if (charBuffer.hasRemaining()){
                // 写入字符集合
                charBuffer.get(tmp);
                // 打印数据
                System.out.println(tmp);
            }

            // 计算下次从那里开始读,未写入部分不计入。
            nowLength = nowLength + intervalSize - (byteBuffer.limit() - byteBuffer.position());
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌白在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值