gpt4 book ai didi

java - 根据编码计算字符字节长度的有效方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:51:50 25 4
gpt4 key购买 nike

在考虑字符编码的情况下,计算字符字节长度的最有效方法是什么?编码只会在运行时才知道。例如,在 UTF-8 中,字符具有可变字节长度,因此需要单独确定每个字符。到目前为止,我已经想出了这个:

char c = getCharSomehow();
String encoding = getEncodingSomehow();
// ...
int length = new String(new char[] { c }).getBytes(encoding).length;

但这在循环中很笨拙且效率低下,因为每次都需要创建一个 new String。我在 Java API 中找不到其他更有效的方法。有一个 String#valueOf(char) ,但根据其来源,它与上述基本相同。我想这可以通过位移位等按位操作来完成,但这是我的弱点,我不确定如何在这里考虑编码:)

如果您质疑这样做的必要性,请检查 this topic .


更新来自@Bkkbrad的答案技术上是最有效的:

char c = getCharSomehow();
String encoding = getEncodingSomehow();
CharsetEncoder encoder = Charset.forName(encoding).newEncoder();
// ...
int length = encoder.encode(CharBuffer.wrap(new char[] { c })).limit();

但是作为@Stephen C指出,这还有更多问题。例如,可能还有需要考虑的组合/代理字符。但这是另一个需要在这一步之前的步骤中解决的问题。

最佳答案

使用 CharsetEncoder并重复使用 CharBuffer作为输入和 ByteBuffer作为输出。

在我的系统上,以下代码需要 25 秒来编码 100,000 个单个字符:

Charset utf8 = Charset.forName("UTF-8");
char[] array = new char[1];
for (int reps = 0; reps < 10000; reps++) {
for (array[0] = 0; array[0] < 10000; array[0]++) {
int len = new String(array).getBytes(utf8).length;
}
}

但是,下面的代码在不到 4 秒的时间内完成了同样的事情:

Charset utf8 = Charset.forName("UTF-8");
CharsetEncoder encoder = utf8.newEncoder();
char[] array = new char[1];
CharBuffer input = CharBuffer.wrap(array);
ByteBuffer output = ByteBuffer.allocate(10);
for (int reps = 0; reps < 10000; reps++) {
for (array[0] = 0; array[0] < 10000; array[0]++) {
output.clear();
input.clear();
encoder.encode(input, output, false);
int len = output.position();
}
}

编辑:仇恨者为什么要仇恨?

这是一个从 CharBuffer 读取并跟踪 surrogate pairs 的解决方案:

Charset utf8 = Charset.forName("UTF-8");
CharsetEncoder encoder = utf8.newEncoder();
CharBuffer input = //allocate in some way, or pass as parameter
ByteBuffer output = ByteBuffer.allocate(10);

int limit = input.limit();
while(input.position() < limit) {
output.clear();
input.mark();
input.limit(Math.max(input.position() + 2, input.capacity()));
if (Character.isHighSurrogate(input.get()) && !Character.isLowSurrogate(input.get())) {
//Malformed surrogate pair; do something!
}
input.limit(input.position());
input.reset();
encoder.encode(input, output, false);
int encodedLen = output.position();
}

关于java - 根据编码计算字符字节长度的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2726071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com