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; // 无效的起始字节
}