OKhttp处理流式API字符截断

StringBuilder stringBuilder = new StringBuilder();
Buffer累积Buffer = new Buffer(); // 累积未处理的字节

try (Response response = httpClient.newCall(httpRequest).execute()) {
    okhttp3.ResponseBody body = response.body();
    if (body == null) return;

    BufferedSource source = body.source();

    while (!source.exhausted()) {
        long read = source.read(累积Buffer, 256); // 直接读取到累积Buffer
        processAccumulatedBuffer(累积Buffer, emitter, buffer1, stringBuilder);
    }

    // 处理最后残留数据
    processAccumulatedBuffer(累积Buffer, emitter, buffer1, stringBuilder);

    if (buffer1.length() > 0) {
        emitter.send(buffer1.toString().trim());
    }
}
logResponseChunk(getLogFilePath(), stringBuilder.toString());

// 处理累积缓冲区中的数据,确保不分割UTF-8字符
private void processAccumulatedBuffer(Buffer buffer, Emitter emitter, Buffer buffer1, StringBuilder logBuilder) {
    while (true) {
        long validUpTo = findLastValidUtf8Position(buffer);
        if (validUpTo == 0) break;

        String chunk = buffer.readUtf8(validUpTo);
        processStreamData(emitter, chunk, buffer1, logBuilder);
    }
}

// 找到最后一个完整UTF-8字符的结束位置
private long findLastValidUtf8Position(Buffer buffer) {
    long size = buffer.size();
    if (size == 0) return 0;

    long position = size - 1;
    while (position >= 0) {
        byte b = buffer.getByte(position);
        int expectedLength = getExpectedUtf8Length(b);
        if (expectedLength == 0) {
            position--;
            continue;
        }
        long available = size - position;
        if (available >= expectedLength) {
            boolean valid = true;
            for (int i = 1; i < expectedLength; i++) {
                byte next = buffer.getByte(position + i);
                if ((next & 0xC0) != 0x80) {
                    valid = false;
                    break;
                }
            }
            if (valid) {
                return position + expectedLength;
            }
        }
        position--;
    }
    return 0;
}

// 根据起始字节判断期望的UTF-8字符长度
private int getExpectedUtf8Length(byte b) {
    if ((b & 0x80) == 0x00) return 1; // 1字节字符
    if ((b & 0xE0) == 0xC0) return 2; // 2字节字符
    if ((b & 0xF0) == 0xE0) return 3; // 3字节字符
    if ((b & 0xF8) == 0xF0) return 4; // 4字节字符
    return 0; // 无效的起始字节
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值